Difference between revisions of "Compiling in constants"

From HaskellWiki
Jump to navigation Jump to search
(bytestring literals compiled in)
 
(data stored in C example)
 
(One intermediate revision by the same user not shown)
Line 16: Line 16:
 
--
 
--
 
mytable =
 
mytable =
  +
"\US\139\b\NUL\NUL\NUL\NUL\NUL\NUL\ETXEN\
"\US\139\b\NUL\NUL\NUL\NUL\NUL\NUL\ETXEN\219\SO\194 \f\197\224\188\196\CAN\227\US\224\171~\NAKc\GS4ce\161`\178\191\215(\176\190\180\167\231\210\n\241\171\203\191\ti\157\217\149\249< \ENQ\214\&9>\202\162\179a\132X\233\ESC=\231\215\164\SYN\157\DC2D\226*\146\174o\t\167\DLE\209\"i_\240\193\129\199<W\250nC\CAN\212\CAN\162J\160\141C\178\133\216;\\@4\144-W\203\209x\205\140\166\RS\163\237]9f\170\143\ACK\163g\223\STX\184\&7\rH\222\FSW\130\&7D\197\NUL\164\&0U\193\186\t\186o\228\180~\NUL\a6\249\137#\SOH\NUL\NUL"
 
  +
\\219\SO\194 \f\197\224\188\196\CAN\227\US\
 
  +
\\224\171~\NAKc\GS4ce\161`\178\191\215(\176\
  +
\\190\180\167\231\210\n\241\171\203\191\ti\
  +
\\157\217\149\249< \ENQ\214\&9>\202\162\179a\
  +
\\132X\233\ESC=\231\215\164\SYN\157\DC2D\226*\
  +
\\146\174o\t\167\DLE\209\"i_\240\193\129\199<W\
  +
\\250nC\CAN\212\CAN\162J\160\141C\178\133\216;\
  +
\\\@4\144-W\203\209x\205\140\166\RS\163\237]9f\
  +
\\170\143\ACK\163g\223\STX\184\&7\rH\222\FSW\
  +
\\130\&7D\197\NUL\164\&0U\193\186\t\186o\
  +
\\228\180~\NUL\a6\249\137#\SOH\NUL\NUL"
   
 
main = print =<< M.lookup "ghc" m
 
main = print =<< M.lookup "ghc" m
Line 33: Line 43:
   
 
</haskell>
 
</haskell>
  +
  +
===Storing the structure in C===
  +
  +
For very large constant data, its more efficient to bypass the
  +
Haskell frontend, and store the structure in C code.
  +
  +
In this case, we'd take the compressed encoded structure, translate
  +
it to a C array type, then access it as a Ptr Word8 from Haskell.
  +
That Word8 Ptr can be used to build a bytestring, which can in turn be
  +
rehydrated via Data.Binary.
  +
  +
A full example is here: http://code.haskell.org/~dons/code/compiled-constants
   
 
[[Category:Tutorials]]
 
[[Category:Tutorials]]

Latest revision as of 22:26, 3 March 2008

An example where a data structure constant is compiled into the source. To avoid excessive compilation time, we pack the structure into a bytestring literal (and gzip it for fun).

{-# LANGUAGE OverloadedStrings #-}

import Data.Binary
import qualified Data.Map as M
import qualified Data.ByteString.Char8 as S
import Data.ByteString.Lazy
import Codec.Compression.GZip

--
-- this is a gzip compressed literal bytestring, storing a binary-encoded Data.Map
--
mytable =
    "\US\139\b\NUL\NUL\NUL\NUL\NUL\NUL\ETXEN\
    \\219\SO\194 \f\197\224\188\196\CAN\227\US\
    \\224\171~\NAKc\GS4ce\161`\178\191\215(\176\
    \\190\180\167\231\210\n\241\171\203\191\ti\
    \\157\217\149\249< \ENQ\214\&9>\202\162\179a\
    \\132X\233\ESC=\231\215\164\SYN\157\DC2D\226*\
    \\146\174o\t\167\DLE\209\"i_\240\193\129\199<W\
    \\250nC\CAN\212\CAN\162J\160\141C\178\133\216;\
    \\\@4\144-W\203\209x\205\140\166\RS\163\237]9f\
    \\170\143\ACK\163g\223\STX\184\&7\rH\222\FSW\
    \\130\&7D\197\NUL\164\&0U\193\186\t\186o\
    \\228\180~\NUL\a6\249\137#\SOH\NUL\NUL"

main = print =<< M.lookup "ghc" m
    where
        -- build the table from the bytestring:
        m :: M.Map String (Maybe String)
        m = decode . decompress . fromChunks . return $ mytable

Running this:

    $ ./A
    Just "dinosaur!"

Storing the structure in C

For very large constant data, its more efficient to bypass the Haskell frontend, and store the structure in C code.

In this case, we'd take the compressed encoded structure, translate it to a C array type, then access it as a Ptr Word8 from Haskell. That Word8 Ptr can be used to build a bytestring, which can in turn be rehydrated via Data.Binary.

A full example is here: http://code.haskell.org/~dons/code/compiled-constants