Skip to content
Browse files

Use unchecked shifts for a speedup.

--HG--
extra : convert_revision : 0af617e20297244e7dc2c99de8af3fe7cfd01ec2
  • Loading branch information...
1 parent 47f25e1 commit 62aa9687ba87a0f2c2c14fdf9ff4d2ab93bed13d @bos committed Jun 3, 2009
View
2 Data/Text/Encoding/Fusion.hs
@@ -32,12 +32,12 @@ module Data.Text.Encoding.Fusion
) where
import Control.Exception (assert)
-import Data.Bits (shiftL)
import Data.ByteString as B
import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
import Data.Text.Fusion (Step(..), Stream(..))
import Data.Text.Encoding.Fusion.Common
import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
+import Data.Text.UnsafeShift (shiftL)
import Data.Word (Word8, Word16, Word32)
import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
import Foreign.Storable (pokeByteOff)
View
3 Data/Text/Encoding/Fusion/Common.hs
@@ -27,10 +27,11 @@ module Data.Text.Encoding.Fusion.Common
, restreamUtf32BE
) where
-import Data.Bits (shiftR, (.&.))
+import Data.Bits ((.&.))
import Data.Char (ord)
import Data.Text.Fusion (Step(..), Stream(..))
import Data.Text.Fusion.Internal (M(..), S(..))
+import Data.Text.UnsafeShift (shiftR)
import Data.Word (Word8)
import qualified Data.Text.Encoding.Utf8 as U8
View
3 Data/Text/Encoding/Utf8.hs
@@ -32,7 +32,8 @@ module Data.Text.Encoding.Utf8
import Control.Exception (assert)
import Data.Char (ord)
-import Data.Bits (shiftR, (.&.))
+import Data.Bits ((.&.))
+import Data.Text.UnsafeShift (shiftR)
import GHC.Exts
import GHC.Word (Word8(..))
View
3 Data/Text/Fusion.hs
@@ -50,10 +50,11 @@ module Data.Text.Fusion
import Prelude (Bool(..), Char, Eq(..), Maybe(..), Monad(..), Int,
Num(..), Ord(..), ($), (&&),
fromIntegral, otherwise)
-import Data.Bits ((.&.), shiftR)
+import Data.Bits ((.&.))
import Data.Char (ord)
import Data.Text.Internal (Text(..))
import Data.Text.UnsafeChar (unsafeChr, unsafeWrite)
+import Data.Text.UnsafeShift (shiftR)
import qualified Data.Text.Array as A
import qualified Data.Text.Fusion.Common as S
import Data.Text.Fusion.Internal
View
3 Data/Text/UnsafeChar.hs
@@ -24,8 +24,9 @@ module Data.Text.UnsafeChar
import Control.Exception (assert)
import Control.Monad.ST (ST)
-import Data.Bits ((.&.), shiftR)
+import Data.Bits ((.&.))
import Data.Char (ord)
+import Data.Text.UnsafeShift (shiftR)
import GHC.Exts (Char(..), chr#, word2Int#)
import GHC.Word (Word8(..), Word16(..), Word32(..))
import qualified Data.Text.Array as A
View
67 Data/Text/UnsafeShift.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE MagicHash #-}
+
+-- |
+-- Module : Data.Text.UnsafeShift
+-- Copyright : (c) Bryan O'Sullivan 2009
+--
+-- License : BSD-style
+-- Maintainer : bos@serpentine.com, rtharper@aftereternity.co.uk,
+-- duncan@haskell.org
+-- Stability : experimental
+-- Portability : GHC
+--
+-- Fast, unchecked bit shifting functions.
+
+module Data.Text.UnsafeShift
+ (
+ UnsafeShift(..)
+ ) where
+
+import qualified Data.Bits as Bits
+import GHC.Base
+import GHC.Word
+
+-- | This is a workaround for poor optimisation in GHC 6.8.2. It
+-- fails to notice constant-width shifts, and adds a test and branch
+-- to every shift. This imposes about a 10% performance hit.
+--
+-- These functions are undefined when the amount being shifted by is
+-- greater than the size in bits of a machine Int#.
+class UnsafeShift a where
+ shiftL :: a -> Int -> a
+ shiftR :: a -> Int -> a
+
+instance UnsafeShift Word16 where
+ {-# INLINE shiftL #-}
+ shiftL (W16# x#) (I# i#) = W16# (x# `uncheckedShiftL#` i#)
+
+ {-# INLINE shiftR #-}
+ shiftR (W16# x#) (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
+
+instance UnsafeShift Word32 where
+ {-# INLINE shiftL #-}
+ shiftL (W32# x#) (I# i#) = W32# (x# `uncheckedShiftL#` i#)
+
+ {-# INLINE shiftR #-}
+ shiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
+
+instance UnsafeShift Word64 where
+ {-# INLINE shiftL #-}
+ shiftL (W64# x#) (I# i#) = W64# (x# `uncheckedShiftL64#` i#)
+
+ {-# INLINE shiftR #-}
+ shiftR (W64# x#) (I# i#) = W64# (x# `uncheckedShiftRL64#` i#)
+
+instance UnsafeShift Int where
+ {-# INLINE shiftL #-}
+ shiftL (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
+
+ {-# INLINE shiftR #-}
+ shiftR (I# x#) (I# i#) = I# (x# `iShiftRA#` i#)
+
+instance UnsafeShift Integer where
+ {-# INLINE shiftL #-}
+ shiftL = Bits.shiftL
+
+ {-# INLINE shiftR #-}
+ shiftR = Bits.shiftR
View
1 text.cabal
@@ -34,6 +34,7 @@ library
Data.Text.Lazy.Internal
Data.Text.Unsafe
Data.Text.UnsafeChar
+ Data.Text.UnsafeShift
Data.Text.Encoding.Utf8
Data.Text.Encoding.Utf16
Data.Text.Encoding.Utf32

0 comments on commit 62aa968

Please sign in to comment.
Something went wrong with that request. Please try again.