on master help sign in
Use unchecked shifts for a speedup.
62aa968Bryan O'Sullivan
Data/Text/Encoding/Fusion.hs+1−1
@@ -32,12 +32,12 @@ module Data.Text.Encoding.Fusion
32 ) where
32 ) where
33
33
34import Control.Exception (assert)
34import Control.Exception (assert)
35−import Data.Bits (shiftL)
36import Data.ByteString as B
35import Data.ByteString as B
37import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
36import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
38import Data.Text.Fusion (Step(..), Stream(..))
37import Data.Text.Fusion (Step(..), Stream(..))
39import Data.Text.Encoding.Fusion.Common
38import Data.Text.Encoding.Fusion.Common
40import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
39import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
40+import Data.Text.UnsafeShift (shiftL)
41import Data.Word (Word8, Word16, Word32)
41import Data.Word (Word8, Word16, Word32)
42import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
42import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
43import Foreign.Storable (pokeByteOff)
43import Foreign.Storable (pokeByteOff)
Data/Text/Encoding/Fusion/Common.hs+2−1
@@ -27,10 +27,11 @@ module Data.Text.Encoding.Fusion.Common
27 , restreamUtf32BE
27 , restreamUtf32BE
28 ) where
28 ) where
29
29
30−import Data.Bits (shiftR, (.&.))
30+import Data.Bits ((.&.))
31import Data.Char (ord)
31import Data.Char (ord)
32import Data.Text.Fusion (Step(..), Stream(..))
32import Data.Text.Fusion (Step(..), Stream(..))
33import Data.Text.Fusion.Internal (M(..), S(..))
33import Data.Text.Fusion.Internal (M(..), S(..))
34+import Data.Text.UnsafeShift (shiftR)
34import Data.Word (Word8)
35import Data.Word (Word8)
35import qualified Data.Text.Encoding.Utf8 as U8
36import qualified Data.Text.Encoding.Utf8 as U8
36
37
Data/Text/Encoding/Utf8.hs+2−1
@@ -32,7 +32,8 @@ module Data.Text.Encoding.Utf8
32
32
33import Control.Exception (assert)
33import Control.Exception (assert)
34import Data.Char (ord)
34import Data.Char (ord)
35−import Data.Bits (shiftR, (.&.))
35+import Data.Bits ((.&.))
36+import Data.Text.UnsafeShift (shiftR)
36import GHC.Exts
37import GHC.Exts
37import GHC.Word (Word8(..))
38import GHC.Word (Word8(..))
38
39
Data/Text/Fusion.hs+2−1
@@ -50,10 +50,11 @@ module Data.Text.Fusion
50import Prelude (Bool(..), Char, Eq(..), Maybe(..), Monad(..), Int,
50import Prelude (Bool(..), Char, Eq(..), Maybe(..), Monad(..), Int,
51 Num(..), Ord(..), ($), (&&),
51 Num(..), Ord(..), ($), (&&),
52 fromIntegral, otherwise)
52 fromIntegral, otherwise)
53−import Data.Bits ((.&.), shiftR)
53+import Data.Bits ((.&.))
54import Data.Char (ord)
54import Data.Char (ord)
55import Data.Text.Internal (Text(..))
55import Data.Text.Internal (Text(..))
56import Data.Text.UnsafeChar (unsafeChr, unsafeWrite)
56import Data.Text.UnsafeChar (unsafeChr, unsafeWrite)
57+import Data.Text.UnsafeShift (shiftR)
57import qualified Data.Text.Array as A
58import qualified Data.Text.Array as A
58import qualified Data.Text.Fusion.Common as S
59import qualified Data.Text.Fusion.Common as S
59import Data.Text.Fusion.Internal
60import Data.Text.Fusion.Internal
Data/Text/UnsafeChar.hs+2−1
@@ -24,8 +24,9 @@ module Data.Text.UnsafeChar
24
24
25import Control.Exception (assert)
25import Control.Exception (assert)
26import Control.Monad.ST (ST)
26import Control.Monad.ST (ST)
27−import Data.Bits ((.&.), shiftR)
27+import Data.Bits ((.&.))
28import Data.Char (ord)
28import Data.Char (ord)
29+import Data.Text.UnsafeShift (shiftR)
29import GHC.Exts (Char(..), chr#, word2Int#)
30import GHC.Exts (Char(..), chr#, word2Int#)
30import GHC.Word (Word8(..), Word16(..), Word32(..))
31import GHC.Word (Word8(..), Word16(..), Word32(..))
31import qualified Data.Text.Array as A
32import qualified Data.Text.Array as A
Data/Text/UnsafeShift.hsnew file+67
@@ -0,0 +1,67 @@
1+{-# LANGUAGE MagicHash #-}
2+
3+-- |
4+-- Module : Data.Text.UnsafeShift
5+-- Copyright : (c) Bryan O'Sullivan 2009
6+--
7+-- License : BSD-style
8+-- Maintainer : bos@serpentine.com, rtharper@aftereternity.co.uk,
9+-- duncan@haskell.org
10+-- Stability : experimental
11+-- Portability : GHC
12+--
13+-- Fast, unchecked bit shifting functions.
14+
15+module Data.Text.UnsafeShift
16+ (
17+ UnsafeShift(..)
18+ ) where
19+
20+import qualified Data.Bits as Bits
21+import GHC.Base
22+import GHC.Word
23+
24+-- | This is a workaround for poor optimisation in GHC 6.8.2. It
25+-- fails to notice constant-width shifts, and adds a test and branch
26+-- to every shift. This imposes about a 10% performance hit.
27+--
28+-- These functions are undefined when the amount being shifted by is
29+-- greater than the size in bits of a machine Int#.
30+class UnsafeShift a where
31+ shiftL :: a -> Int -> a
32+ shiftR :: a -> Int -> a
33+
34+instance UnsafeShift Word16 where
35+ {-# INLINE shiftL #-}
36+ shiftL (W16# x#) (I# i#) = W16# (x# `uncheckedShiftL#` i#)
37+
38+ {-# INLINE shiftR #-}
39+ shiftR (W16# x#) (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
40+
41+instance UnsafeShift Word32 where
42+ {-# INLINE shiftL #-}
43+ shiftL (W32# x#) (I# i#) = W32# (x# `uncheckedShiftL#` i#)
44+
45+ {-# INLINE shiftR #-}
46+ shiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
47+
48+instance UnsafeShift Word64 where
49+ {-# INLINE shiftL #-}
50+ shiftL (W64# x#) (I# i#) = W64# (x# `uncheckedShiftL64#` i#)
51+
52+ {-# INLINE shiftR #-}
53+ shiftR (W64# x#) (I# i#) = W64# (x# `uncheckedShiftRL64#` i#)
54+
55+instance UnsafeShift Int where
56+ {-# INLINE shiftL #-}
57+ shiftL (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
58+
59+ {-# INLINE shiftR #-}
60+ shiftR (I# x#) (I# i#) = I# (x# `iShiftRA#` i#)
61+
62+instance UnsafeShift Integer where
63+ {-# INLINE shiftL #-}
64+ shiftL = Bits.shiftL
65+
66+ {-# INLINE shiftR #-}
67+ shiftR = Bits.shiftR
text.cabal+1
@@ -34,6 +34,7 @@ library
34 Data.Text.Lazy.Internal
34 Data.Text.Lazy.Internal
35 Data.Text.Unsafe
35 Data.Text.Unsafe
36 Data.Text.UnsafeChar
36 Data.Text.UnsafeChar
37+ Data.Text.UnsafeShift
37 Data.Text.Encoding.Utf8
38 Data.Text.Encoding.Utf8
38 Data.Text.Encoding.Utf16
39 Data.Text.Encoding.Utf16
39 Data.Text.Encoding.Utf32
40 Data.Text.Encoding.Utf32