on master help sign in
Eliminate dependency on the array package
a986b8cBryan O'Sullivan
Data/Text.hs+12−13
@@ -112,8 +112,7 @@ import Prelude (Char,Bool,Int,Maybe,String,
112 IO, FilePath)
112 IO, FilePath)
113import Data.Char (isSpace)
113import Data.Char (isSpace)
114import Control.Monad.ST(ST)
114import Control.Monad.ST(ST)
115−import Data.Array.Base(unsafeNewArray_,unsafeWrite,unsafeAt)
115+import qualified Data.Text.Array as A
116−import Data.Array.ST(STUArray, runSTUArray)
117import qualified Data.ByteString as B
116import qualified Data.ByteString as B
118import Data.ByteString(ByteString)
117import Data.ByteString(ByteString)
119import qualified Data.List as L
118import qualified Data.List as L
@@ -218,18 +217,18 @@ snoc t c = unstream (S.snoc (stream t) c)
218-- | /O(n)/ Appends one 'Text' to the other by copying both of them
217-- | /O(n)/ Appends one 'Text' to the other by copying both of them
219-- into a new 'Text'. Subject to array fusion.
218-- into a new 'Text'. Subject to array fusion.
220append :: Text -> Text -> Text
219append :: Text -> Text -> Text
221−append (Text arr1 off1 len1) (Text arr2 off2 len2) = Text (runSTUArray x) 0 len
220+append (Text arr1 off1 len1) (Text arr2 off2 len2) = Text (A.run x) 0 len
222 where
221 where
223 len = len1+len2
222 len = len1+len2
224 x = do
223 x = do
225− arr <- unsafeNewArray_ (0,len-1) :: ST s (STUArray s Int Word16)
224+ arr <- A.unsafeNew len :: ST s (A.MArray s Word16)
226 copy arr1 off1 (len1+off1) arr 0
225 copy arr1 off1 (len1+off1) arr 0
227 copy arr2 off2 (len2+off2) arr len1
226 copy arr2 off2 (len2+off2) arr len1
228 return arr
227 return arr
229 where
228 where
230 copy arr i max arr' j
229 copy arr i max arr' j
231 | i >= max = return ()
230 | i >= max = return ()
232− | otherwise = do unsafeWrite arr' j (arr `unsafeAt` i)
231+ | otherwise = do A.unsafeWrite arr' j (arr `A.unsafeIndex` i)
233 copy arr (i+1) max arr' (j+1)
232 copy arr (i+1) max arr' (j+1)
234{-# INLINE append #-}
233{-# INLINE append #-}
235
234
@@ -254,8 +253,8 @@ last (Text arr off len)
254 | n < 0xDC00 || n > 0xDFFF = unsafeChr n
253 | n < 0xDC00 || n > 0xDFFF = unsafeChr n
255 | otherwise = U16.chr2 n0 n
254 | otherwise = U16.chr2 n0 n
256 where
255 where
257− n = unsafeAt arr (off+len-1)
256+ n = A.unsafeIndex arr (off+len-1)
258− n0 = unsafeAt arr (off+len-2)
257+ n0 = A.unsafeIndex arr (off+len-2)
259{-# INLINE [1] last #-}
258{-# INLINE [1] last #-}
260
259
261{-# RULES
260{-# RULES
@@ -274,7 +273,7 @@ tail (Text arr off len)
274 | n >= 0xD800 && n <= 0xDBFF = Text arr (off+2) (len-2)
273 | n >= 0xD800 && n <= 0xDBFF = Text arr (off+2) (len-2)
275 | otherwise = Text arr (off+1) (len-1)
274 | otherwise = Text arr (off+1) (len-1)
276 where
275 where
277− n = unsafeAt arr off
276+ n = A.unsafeIndex arr off
278{-# INLINE [1] tail #-}
277{-# INLINE [1] tail #-}
279
278
280
279
@@ -286,7 +285,7 @@ init (Text arr off len) | len <= 0 = errorEmptyList "init"
286 | n >= 0xDC00 && n <= 0xDFFF = Text arr off (len-2)
285 | n >= 0xDC00 && n <= 0xDFFF = Text arr off (len-2)
287 | otherwise = Text arr off (len-1)
286 | otherwise = Text arr off (len-1)
288 where
287 where
289− n = unsafeAt arr (off+len-1)
288+ n = A.unsafeIndex arr (off+len-1)
290{-# INLINE [1] init #-}
289{-# INLINE [1] init #-}
291
290
292{-# RULES
291{-# RULES
@@ -305,7 +304,7 @@ null t = S.null (stream t)
305-- | /O(n)/ Returns the number of characters in a 'Text'.
304-- | /O(n)/ Returns the number of characters in a 'Text'.
306-- Subject to array fusion.
305-- Subject to array fusion.
307length :: Text -> Int
306length :: Text -> Int
308−length length t = S.length (stream t)
307+length t = S.length (stream t)
309{-# INLINE length #-}
308{-# INLINE length #-}
310
309
311-- -----------------------------------------------------------------------------
310-- -----------------------------------------------------------------------------
@@ -458,7 +457,7 @@ take n t@(Text arr off len)
458 | c < 0xD800 || c > 0xDBFF = loop (i+1) (count+1)
457 | c < 0xD800 || c > 0xDBFF = loop (i+1) (count+1)
459 | otherwise = loop (i+2) (count+1)
458 | otherwise = loop (i+2) (count+1)
460 where
459 where
461− c = arr `unsafeAt` i
460+ c = arr `A.unsafeIndex` i
462{-# INLINE [1] take #-}
461{-# INLINE [1] take #-}
463
462
464{-# RULES
463{-# RULES
@@ -484,7 +483,7 @@ drop n t@(Text arr off len)
484 | c < 0xD800 || c > 0xDBFF = loop (i+1) (count+1) (l-1)
483 | c < 0xD800 || c > 0xDBFF = loop (i+1) (count+1) (l-1)
485 | otherwise = loop (i+2) (count+1) (l-2)
484 | otherwise = loop (i+2) (count+1) (l-2)
486 where
485 where
487− c = arr `unsafeAt` i
486+ c = arr `A.unsafeIndex` i
488{-# INLINE [1] drop #-}
487{-# INLINE [1] drop #-}
489
488
490{-# RULES
489{-# RULES
@@ -580,7 +579,7 @@ words (Text arr off len) = loop0 off off
580 then []
579 then []
581 else [(Text arr start (n-start))]
580 else [(Text arr start (n-start))]
582 where
581 where
583− c = arr `unsafeAt` n
582+ c = arr `A.unsafeIndex` n
584{-# INLINE words #-}
583{-# INLINE words #-}
585
584
586errorEmptyList :: String -> a
585errorEmptyList :: String -> a
Data/Text/Array.hsnew file+237
@@ -0,0 +1,237 @@
1+{-# LANGUAGE CPP, ExistentialQuantification, MagicHash, Rank2Types,
2+ ScopedTypeVariables, UnboxedTuples #-}
3+-- |
4+-- Module : Data.Text.Array
5+-- Copyright : (c) Bryan O'Sullivan 2009
6+--
7+-- License : BSD-style
8+-- Maintainer : bos@serpentine.com,
9+-- Stability : experimental
10+-- Portability : portable
11+--
12+-- Packed, unboxed, heap-resident arrays. Suitable for performance
13+-- critical use, both in terms of large data quantities and high
14+-- speed.
15+--
16+-- This module is intended to be imported @qualified@, to avoid name
17+-- clashes with "Prelude" functions, e.g.
18+--
19+-- > import qualified Data.Text.Array as A
20+--
21+-- The names in this module resemble those in the 'Data.Array' family
22+-- of modules, but are shorter due to the assumption of qualifid
23+-- naming.
24+module Data.Text.Array
25+ (
26+ -- * Types
27+ IArray(..)
28+ , Elt(..)
29+ , Array
30+ , MArray
31+
32+ -- * Functions
33+ , empty
34+ , new
35+ , unsafeNew
36+ , unsafeFreeze
37+ , run
38+ ) where
39+
40+#if defined(__GLASGOW_HASKELL__)
41+#include "MachDeps.h"
42+
43+import GHC.Base (ByteArray#, MutableByteArray#, indexWord16Array#,
44+ newByteArray#, readWord16Array#, unsafeCoerce#,
45+ writeWord16Array#, (+#), (*#))
46+import GHC.Prim (Int#)
47+import GHC.ST (ST(..), runST)
48+import GHC.Types (Int(..))
49+import GHC.Word (Word16(..))
50+
51+#elif defined(__HUGS__)
52+
53+import Hugs.ByteArray (ByteArray, MutableByteArray, readByteArray,
54+ newMutableByteArray, readMutableByteArray,
55+ unsafeFreezeMutableByteArray, writeMutableByteArray)
56+import Foreign.Storable (Storable, sizeOf)
57+import Hugs.ST (ST(..), runST)
58+
59+#else
60+# error not implemented for this compiler
61+#endif
62+
63+import Data.Typeable
64+import Data.Word (Word16)
65+import Prelude hiding (length, read)
66+
67+#include "Typeable.h"
68+
69+-- | Immutable array type.
70+data Array e = Array
71+ {-# UNPACK #-} !Int -- length (in units of e, not bytes)
72+#if defined(__GLASGOW_HASKELL__)
73+ ByteArray#
74+#elif defined(__HUGS__)
75+ !ByteArray
76+#endif
77+
78+INSTANCE_TYPEABLE1(Array,arrayTc,"Array")
79+
80+-- | Mutable array type, for use in the ST monad.
81+data MArray s e = MArray
82+ {-# UNPACK #-} !Int -- length (in units of e, not bytes)
83+#if defined(__GLASGOW_HASKELL__)
84+ (MutableByteArray# s)
85+#elif defined(__HUGS__)
86+ !(MutableByteArray s)
87+#endif
88+
89+INSTANCE_TYPEABLE2(MArray,mArrayTc,"MArray")
90+
91+-- | Operations supported by all arrays.
92+class IArray a where
93+ -- | Return the length of an array.
94+ length :: a -> Int
95+
96+instance IArray (Array e) where
97+ length (Array len _ba) = len
98+ {-# INLINE length #-}
99+
100+instance IArray (MArray s e) where
101+ length (MArray len _ba) = len
102+ {-# INLINE length #-}
103+
104+check :: IArray a => String -> a -> Int -> (a -> Int -> b) -> b
105+check func ary i f
106+ | i >= 0 && i < length ary = f ary i
107+ | otherwise = error ("Data.Array.Flat." ++ func ++ ": index out of bounds")
108+{-# INLINE check #-}
109+
110+-- | Operations supported by all elements that can be stored in
111+-- arrays.
112+class Elt e where
113+ -- | Indicate how many bytes would be used for an array of the
114+ -- given size.
115+ bytesInArray :: Int -> e -> Int
116+ -- | Unchecked read of an immutable array. May return garbage or
117+ -- crash on an out-of-bounds access.
118+ unsafeIndex :: Array e -> Int -> e
119+ -- | Unchecked read of a mutable array. May return garbage or
120+ -- crash on an out-of-bounds access.
121+ unsafeRead :: MArray s e -> Int -> ST s e
122+ -- | Unchecked write of a mutable array. May return garbage or
123+ -- crash on an out-of-bounds access.
124+ unsafeWrite :: MArray s e -> Int -> e -> ST s ()
125+
126+ -- | Read an immutable array. An invalid index results in a
127+ -- runtime error.
128+ index :: Array e -> Int -> e
129+ index ary i = check "index" ary i unsafeIndex
130+ {-# INLINE index #-}
131+
132+ -- | Read a mutable array. An invalid index results in a runtime
133+ -- error.
134+ read :: Array e -> Int -> ST s e
135+ read ary i = check "read" ary i read
136+ {-# INLINE read #-}
137+
138+ -- | Write a mutable array. An invalid index results in a runtime
139+ -- error.
140+ write :: Array e -> Int -> ST s e
141+ write ary i = check "write" ary i write
142+ {-# INLINE write #-}
143+
144+-- | Freeze a mutable array. Do not mutate the 'MArray' afterwards!
145+unsafeFreeze :: MArray s e -> ST s (Array e)
146+
147+#if defined(__GLASGOW_HASKELL__)
148+
149+wORD16_SCALE :: Int# -> Int#
150+wORD16_SCALE n# = scale# *# n# where I# scale# = SIZEOF_WORD16
151+
152+-- | Create an uninitialized mutable array.
153+unsafeNew :: forall s e. Elt e => Int -> ST s (MArray s e)
154+unsafeNew n = ST $ \s1# ->
155+ case bytesInArray n (undefined :: e) of
156+ (I# len#) -> case newByteArray# len# s1# of
157+ (# s2#, marr# #) -> (# s2#, MArray n marr# #)
158+{-# INLINE unsafeNew #-}
159+
160+unsafeFreeze (MArray len mba#) = ST $ \s# ->
161+ (# s#, Array len (unsafeCoerce# mba#) #)
162+{-# INLINE unsafeFreeze #-}
163+
164+-- | Create a mutable array, with its elements initialized with the
165+-- given value.
166+new :: forall s e. Elt e => Int -> e -> ST s (MArray s e)
167+
168+#elif defined(__HUGS__)
169+
170+unsafeIndexArray :: Storable e => Array e -> Int -> e
171+unsafeIndexArray (Array off _len arr) i = readByteArray arr (off + i)
172+
173+unsafeReadMArray :: Storable e => MArray s e -> Int -> ST s e
174+unsafeReadMArray (MArray _len marr) = readMutableByteArray marr
175+
176+unsafeWriteMArray :: Storable e => MArray s e -> Int -> e -> ST s ()
177+unsafeWriteMArray (MArray _len marr) = writeMutableByteArray marr
178+
179+-- | Create an uninitialized mutable array.
180+unsafeNew :: (Storable e) => Int -> ST s (MArray s e)
181+unsafeNew n = new undefined
182+ where new :: (Storable e) => e -> ST s (MArray s e)
183+ new unused = do
184+ marr <- newMutableByteArray (n * sizeOf unused)
185+ return (MArray n marr)
186+
187+unsafeFreeze (MArray len mba) = do
188+ ba <- unsafeFreezeMutableByteArray mba
189+ return (Array 0 len ba)
190+
191+-- | Create a mutable array, with its elements initialized with the
192+-- given value.
193+new :: (Storable e) => Int -> e -> ST s (MArray s e)
194+#endif
195+
196+new len initVal = do
197+ marr <- unsafeNew len
198+ sequence_ [unsafeWrite marr i initVal | i <- [0..len-1]]
199+ return marr
200+
201+instance Elt Word16 where
202+#if defined(__GLASGOW_HASKELL__)
203+
204+ bytesInArray (I# i#) _ = I# (wORD16_SCALE i#)
205+ {-# INLINE bytesInArray #-}
206+
207+ unsafeIndex (Array _len ba#) (I# i#) =
208+ case indexWord16Array# ba# i# of r# -> (W16# r#)
209+ {-# INLINE unsafeIndex #-}
210+
211+ unsafeRead (MArray _len mba#) (I# i#) = ST $ \s# ->
212+ case readWord16Array# mba# i# s# of
213+ (# s2#, r# #) -> (# s2#, W16# r# #)
214+ {-# INLINE unsafeRead #-}
215+
216+ unsafeWrite (MArray _len marr#) (I# i#) (W16# e#) = ST $ \s1# ->
217+ case writeWord16Array# marr# i# e# s1# of
218+ s2# -> (# s2#, () #)
219+ {-# INLINE unsafeWrite #-}
220+
221+#elif defined(__HUGS__)
222+
223+ bytesInArray n w = sizeOf w * n
224+ unsafeIndex = unsafeIndexArray
225+ unsafeRead = unsafeReadMArray
226+ unsafeWrite = unsafeWriteMArray
227+
228+#endif
229+
230+-- | An empty immutable array.
231+empty :: Elt e => Array e
232+empty = runST (unsafeNew 0 >>= unsafeFreeze)
233+
234+-- | Run an action in the ST monad and return an immutable array of
235+-- its result.
236+run :: Elt e => (forall s. ST s (MArray s e)) -> Array e
237+run k = runST (k >>= unsafeFreeze)
Data/Text/Fusion.hs+19−21
@@ -57,7 +57,6 @@ import Data.Char (ord)
57import Control.Exception(assert)
57import Control.Exception(assert)
58import Control.Monad(liftM2)
58import Control.Monad(liftM2)
59import Control.Monad.ST(runST,ST)
59import Control.Monad.ST(runST,ST)
60−import Data.Array.Base
61import Data.Bits (shiftL, shiftR, (.&.))
60import Data.Bits (shiftL, shiftR, (.&.))
62import qualified Data.ByteString as B
61import qualified Data.ByteString as B
63import qualified Data.ByteString.Unsafe as B
62import qualified Data.ByteString.Unsafe as B
@@ -70,6 +69,7 @@ import GHC.Exts (Int(..), (+#))
70import System.IO.Unsafe(unsafePerformIO)
69import System.IO.Unsafe(unsafePerformIO)
71import Data.Text.Internal(Text(..),empty)
70import Data.Text.Internal(Text(..),empty)
72import Data.Text.UnsafeChar(unsafeChr,unsafeChr8,unsafeChr32)
71import Data.Text.UnsafeChar(unsafeChr,unsafeChr8,unsafeChr32)
72+import qualified Data.Text.Array as A
73import qualified Data.Text.Utf8 as U8
73import qualified Data.Text.Utf8 as U8
74import qualified Data.Text.Utf16 as U16
74import qualified Data.Text.Utf16 as U16
75import qualified Data.Text.Utf32 as U32
75import qualified Data.Text.Utf32 as U32
@@ -103,32 +103,32 @@ stream (Text arr off len) = Stream next off len
103 | n >= 0xD800 && n <= 0xDBFF = Yield (U16.chr2 n n2) (i + 2)
103 | n >= 0xD800 && n <= 0xDBFF = Yield (U16.chr2 n n2) (i + 2)
104 | otherwise = Yield (unsafeChr n) (i + 1)
104 | otherwise = Yield (unsafeChr n) (i + 1)
105 where
105 where
106− n = unsafeAt arr i
106+ n = A.unsafeIndex arr i
107− n2 = unsafeAt arr (i + 1)
107+ n2 = A.unsafeIndex arr (i + 1)
108{-# INLINE [0] stream #-}
108{-# INLINE [0] stream #-}
109
109
110-- | /O(n)/ Convert a Stream Char into a Text.
110-- | /O(n)/ Convert a Stream Char into a Text.
111unstream :: Stream Char -> Text
111unstream :: Stream Char -> Text
112unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
112unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
113 where
113 where
114− a :: ((UArray Int Word16),Int)
114+ a :: ((A.Array Word16),Int)
115− a = runST ((unsafeNewArray_ (0,len+1) :: ST s (STUArray s Int Word16))
115+ a = runST ((A.unsafeNew len :: ST s (A.MArray s Word16))
116− >>= (\arr -> loop arr 0 (len+1) s0))
116+ >>= (\arr -> loop arr 0 len s0))
117 loop arr !i !top !s
117 loop arr !i !top !s
118− | i + 1 > top = do arr' <- unsafeNewArray_ (0,top*2)
118+ | i + 1 > top = do arr' <- A.unsafeNew (top*2)
119 case next0 s of
119 case next0 s of
120− Done -> liftM2 (,) (unsafeFreezeSTUArray arr) (return i)
120+ Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
121 _ -> copy arr arr' >> loop arr' i (top*2) s
121 _ -> copy arr arr' >> loop arr' i (top*2) s
122 | otherwise = case next0 s of
122 | otherwise = case next0 s of
123− Done -> liftM2 (,) (unsafeFreezeSTUArray arr) (return i)
123+ Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
124 Skip s' -> loop arr i top s'
124 Skip s' -> loop arr i top s'
125 Yield x s'
125 Yield x s'
126 | n < 0x10000 -> do
126 | n < 0x10000 -> do
127− unsafeWrite arr i (fromIntegral n :: Word16)
127+ A.unsafeWrite arr i (fromIntegral n :: Word16)
128 loop arr (i+1) top s'
128 loop arr (i+1) top s'
129 | otherwise -> do
129 | otherwise -> do
130− unsafeWrite arr i l
130+ A.unsafeWrite arr i l
131− unsafeWrite arr (i + 1) r
131+ A.unsafeWrite arr (i + 1) r
132 loop arr (i+2) top s'
132 loop arr (i+2) top s'
133 where
133 where
134 n :: Int
134 n :: Int
@@ -142,16 +142,14 @@ unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
142{-# INLINE [0] unstream #-}
142{-# INLINE [0] unstream #-}
143
143
144
144
145−copy :: STUArray s Int Word16 -> STUArray s Int Word16 -> ST s ()
145+copy :: A.MArray s Word16 -> A.MArray s Word16 -> ST s ()
146−copy src dest = (do
146+copy src dest = copy_loop 0
147− (_,top) <- getBounds src
148− copy_loop 0 top)
149 where
147 where
148+ len = A.length src
150− copy_loop i top
149+ copy_loop i
151− | i > top = return ()
150+ | i > len = return ()
152− | otherwise = do v <- unsafeRead src i
151+ | otherwise = do A.unsafeRead src i >>= A.unsafeWrite dest i
153− unsafeWrite dest i v
154− copy_loop (i+1) top
152+ copy_loop (i+1)
155
153
156-- | /O(n)/ Determines if two streams are equal.
154-- | /O(n)/ Determines if two streams are equal.
157eq :: Ord a => Stream a -> Stream a -> Bool
155eq :: Ord a => Stream a -> Stream a -> Bool
Data/Text/Internal.hs+5−6
@@ -23,18 +23,17 @@ module Data.Text.Internal
23 , empty
23 , empty
24 ) where
24 ) where
25
25
26−import Data.Array.ST (newArray_,runSTUArray)
26+import qualified Data.Text.Array as A
27−import Data.Array.Unboxed (UArray)
28import Data.Typeable (Typeable)
27import Data.Typeable (Typeable)
29import Data.Word (Word16)
28import Data.Word (Word16)
30
29
31-- | A space efficient, packed, unboxed Unicode text type.
30-- | A space efficient, packed, unboxed Unicode text type.
32−data Text = Text {-# UNPACK #-} !(UArray Int Word16) -- payload
31+data Text = Text {-# UNPACK #-} !(A.Array Word16) -- payload
33− {-# UNPACK #-} !Int -- offset
32+ {-# UNPACK #-} !Int -- offset
34− {-# UNPACK #-} !Int -- length
33+ {-# UNPACK #-} !Int -- length
35 deriving (Typeable)
34 deriving (Typeable)
36
35
37-- | /O(1)/ The empty 'Text'.
36-- | /O(1)/ The empty 'Text'.
38empty :: Text
37empty :: Text
39−empty = Text (runSTUArray (newArray_ (0,0))) 0 0
38+empty = Text A.empty 0 0
40{-# INLINE [1] empty #-}
39{-# INLINE [1] empty #-}
tests/Bench.hs+7−17
@@ -17,36 +17,25 @@ import qualified Data.Text.Fusion as S
17import Data.Text.Fusion (Encoding(..))
17import Data.Text.Fusion (Encoding(..))
18
18
19import qualified Data.List as L
19import qualified Data.List as L
20−import qualified Data.ByteString as B
20+import qualified Data.ByteString.Char8 as B
21+import qualified Data.ByteString as B8
21import Data.ByteString (ByteString)
22import Data.ByteString (ByteString)
22import Data.Word
23import Data.Word
23import qualified System.IO.UTF8 as UTF8
24import qualified System.IO.UTF8 as UTF8
24
25
25−main = do ascii_bs <- B.readFile "ascii.txt"
26+main = do ascii_bs <- B.readFile "text/test/ascii.txt"
26 let ascii_txt = T.decode ASCII ascii_bs
27 let ascii_txt = T.decode ASCII ascii_bs
27 let ascii_str = T.unpack ascii_txt
28 let ascii_str = T.unpack ascii_txt
28 force (ascii_txt,ascii_str,ascii_bs)
29 force (ascii_txt,ascii_str,ascii_bs)
29 printf " # Text\t\tString\tByteString\n"
30 printf " # Text\t\tString\tByteString\n"
30 run 1 (ascii_txt,ascii_str,ascii_bs) ascii_tests
31 run 1 (ascii_txt,ascii_str,ascii_bs) ascii_tests
31− performGC
32− bmp_txt <- T.readFile Utf8 "bmp.txt"
33− let bmp_str = T.unpack bmp_txt
34− force (bmp_txt,bmp_str)
35− printf " # Text\t\tString\t\n"
36− run 1 (bmp_txt, bmp_str, B.empty) bmp_tests
37− performGC
38− smp_sip_txt <- T.readFile Utf8 "smp_sip.txt"
39− let smp_sip_str = T.unpack smp_sip_txt
40− force (smp_sip_txt, smp_sip_str)
41− printf " # Text\t\tString\t\n"
42− run 1 (smp_sip_txt, smp_sip_str,B.empty) smp_sip_tests
43
32
44
33
45ascii_tests = [
34ascii_tests = [
46 ("cons",
35 ("cons",
47 [F (app1 (T.cons '\88')),
36 [F (app1 (T.cons '\88')),
48 F (app2 ((:) '\88') ),
37 F (app2 ((:) '\88') ),
49− F (app3 (B.cons 88) )]),
38+ F (app3 (B8.cons 88) )]),
50 ("head",
39 ("head",
51 [F (app1 T.head),
40 [F (app1 T.head),
52 F (app2 L.head),
41 F (app2 L.head),
@@ -78,7 +67,7 @@ ascii_tests = [
78 ("filter",
67 ("filter",
79 [F $ app1 $ T.filter (/= '\101'),
68 [F $ app1 $ T.filter (/= '\101'),
80 Flist $ app2 $ L.filter (/= '\101'),
69 Flist $ app2 $ L.filter (/= '\101'),
81− F $ app3 $ B.filter (/= 101)]),
70+ F $ app3 $ B8.filter (/= 101)]),
82 ("foldl'",
71 ("foldl'",
83 [F (app1 $ T.foldl' (\a w -> a+1::Int) 0),
72 [F (app1 $ T.foldl' (\a w -> a+1::Int) 0),
84 F (app2 $ L.foldl' (\a w -> a+1::Int) 0),
73 F (app2 $ L.foldl' (\a w -> a+1::Int) 0),
@@ -95,7 +84,8 @@ ascii_tests = [
95 F (app3 $ B.take 30000000)]),
84 F (app3 $ B.take 30000000)]),
96 ("words",
85 ("words",
97 [F (app1 $ T.words),
86 [F (app1 $ T.words),
98− Flist (app2 $ L.words)])
87+ Flist (app2 $ L.words),
88+ F (app3 $ B.words)])
99 ]
89 ]
100
90
101bmp_tests = [
91bmp_tests = [
tests/FusionBench.hs+3−1
@@ -1,4 +1,4 @@
1−import Prelude hiding (zip,zip3,fst,snd)
1+import Prelude hiding (zip,zip3)
2
2
3import BenchUtils
3import BenchUtils
4import Data.Char
4import Data.Char
@@ -19,6 +19,8 @@ main = do ascii_str <- readFile "ascii.txt"
19 printf " # Text\t\tString\tByteString\n"
19 printf " # Text\t\tString\tByteString\n"
20 run 1 (ascii_txt,ascii_str,ascii_bs) ascii_tests
20 run 1 (ascii_txt,ascii_str,ascii_bs) ascii_tests
21
21
22+trd (a,b,c) = c
23+
22ascii_tests = [
24ascii_tests = [
23 ("map/map",
25 ("map/map",
24 [F $ T.map pred . T.map succ . fst,
26 [F $ T.map pred . T.map succ . fst,
text.cabal+3−3
@@ -17,6 +17,7 @@ cabal-version: >= 1.2
17library
17library
18 exposed-modules:
18 exposed-modules:
19 Data.Text
19 Data.Text
20+ Data.Text.Array
20 Data.Text.UnsafeChar
21 Data.Text.UnsafeChar
21 Data.Text.Internal
22 Data.Text.Internal
22 Data.Text.Fusion
23 Data.Text.Fusion
@@ -25,12 +26,11 @@ library
25 Data.Text.Utf16
26 Data.Text.Utf16
26
27
27 build-depends:
28 build-depends:
28− base >= 3 && < 4,
29+ base < 5,
29− array >= 0.1 && < 0.3,
30 bytestring >= 0.9 && < 1.0
30 bytestring >= 0.9 && < 1.0
31 if impl(ghc >= 6.10)
31 if impl(ghc >= 6.10)
32 build-depends:
32 build-depends:
33− ghc-prim
33+ ghc-prim, base >= 4
34
34
35 -- gather extensive profiling data for now
35 -- gather extensive profiling data for now
36 ghc-prof-options: -auto-all
36 ghc-prof-options: -auto-all