Commits

Bryan O'Sullivan committed fa76866

Use unchecked shifts for a speedup.

Comments (0)

Files changed (7)

Data/Text/Encoding/Fusion.hs

     ) 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)

Data/Text/Encoding/Fusion/Common.hs

     , 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
 

Data/Text/Encoding/Utf8.hs

 
 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(..))
 

Data/Text/Fusion.hs

 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

Data/Text/UnsafeChar.hs

 
 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

Data/Text/UnsafeShift.hs

+{-# 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
     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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.