Skip to content

Commit

Permalink
Make use of assert conditional
Browse files Browse the repository at this point in the history
This turns out to make about a 10% difference to performance, even
though the GHC docs claim it shouldn't :-(

--HG--
extra : convert_revision : 446f05ea889a715272cd709cbd2d3b11260df7ba
  • Loading branch information
bos committed Aug 15, 2010
1 parent eac9147 commit a99b318
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 66 deletions.
8 changes: 7 additions & 1 deletion Data/Text.hs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
#if defined(HAVE_DEEPSEQ)
import Control.DeepSeq (NFData)
#endif
#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import Data.Char (isSpace)
import Data.Data (Data(gfoldl, toConstr, gunfold, dataTypeOf))
#if __GLASGOW_HASKELL__ >= 612
Expand Down Expand Up @@ -395,7 +397,11 @@ init (Text arr off len) | len <= 0 = emptyError "init"
-- | /O(1)/ Tests whether a 'Text' is empty or not. Subject to
-- fusion.
null :: Text -> Bool
null (Text _arr _off len) = assert (len >= 0) $ len <= 0
null (Text _arr _off len) =
#if defined(ASSERTS)
assert (len >= 0) $
#endif
len <= 0
{-# INLINE [1] null #-}

{-# RULES
Expand Down
23 changes: 15 additions & 8 deletions Data/Text/Array.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,20 @@ module Data.Text.Array
, unsafeWrite
) where

#if 0
#define BOUNDS_CHECKING
#if defined(ASSERTS)
-- This fugly hack is brought by GHC's apparent reluctance to deal
-- with MagicHash and UnboxedTuples when inferring types. Eek!
#define CHECK_BOUNDS(_func_,_len_,_k_) \
# define CHECK_BOUNDS(_func_,_len_,_k_) \
if (_k_) < 0 || (_k_) >= (_len_) then error ("Data.Text.Array." ++ (_func_) ++ ": bounds error, offset " ++ show (_k_) ++ ", length " ++ show (_len_)) else
#else
#define CHECK_BOUNDS(_func_,_len_,_k_)
# define CHECK_BOUNDS(_func_,_len_,_k_)
#endif

#include "MachDeps.h"

#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import Data.Text.UnsafeShift (shiftL)
import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
indexWord16Array#, newByteArray#,
Expand Down Expand Up @@ -92,10 +93,14 @@ unsafeFreeze :: MArray s -> ST s (Array)

-- | Create an uninitialized mutable array.
unsafeNew :: forall s. Int -> ST s (MArray s)
unsafeNew n = assert (n >= 0) . ST $ \s1# ->
case bytesInArray n of
len@(I# len#) ->
#if defined(BOUNDS_CHECKING)
unsafeNew n =
#if defined(ASSERTS)
assert (n >= 0) .
#endif
ST $ \s1# ->
case bytesInArray n of
len@(I# len#) ->
#if defined(ASSERTS)
if len < 0 then error (show ("unsafeNew",len)) else
#endif
case newByteArray# len# s1# of
Expand Down Expand Up @@ -181,8 +186,10 @@ copy src dest
-- | Unsafely copy the elements of an array.
unsafeCopy :: MArray s -> Int -> MArray s -> Int -> Int -> ST s ()
unsafeCopy src sidx dest didx count =
#if defined(ASSERTS)
assert (sidx + count <= length src) .
assert (didx + count <= length dest) $
#endif
copy_loop sidx didx 0
where
copy_loop !i !j !c
Expand Down
10 changes: 8 additions & 2 deletions Data/Text/Encoding/Fusion.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE BangPatterns, Rank2Types #-}
{-# LANGUAGE BangPatterns, CPP, Rank2Types #-}

-- |
-- Module : Data.Text.Encoding.Fusion
Expand Down Expand Up @@ -31,7 +31,9 @@ module Data.Text.Encoding.Fusion
, module Data.Text.Encoding.Fusion.Common
) where

#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
import Data.Text.Fusion (Step(..), Stream(..))
import Data.Text.Fusion.Size
Expand Down Expand Up @@ -182,7 +184,11 @@ unstream (Stream next s0 len) = unsafePerformIO $ do
{-# NOINLINE trimUp #-}
trimUp fp _ off = return $! PS fp 0 off
copy0 :: ForeignPtr Word8 -> Int -> Int -> IO (ForeignPtr Word8)
copy0 !src !srcLen !destLen = assert (srcLen <= destLen) $ do
copy0 !src !srcLen !destLen =
#if defined(ASSERTS)
assert (srcLen <= destLen) $
#endif
do
dest <- mallocByteString destLen
withForeignPtr src $ \src' ->
withForeignPtr dest $ \dest' ->
Expand Down
2 changes: 1 addition & 1 deletion Data/Text/Encoding/Fusion/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ module Data.Text.Encoding.Fusion.Common
) where

import Data.Bits ((.&.))
import Data.Char (ord)
import Data.Text.Fusion (Step(..), Stream(..))
import Data.Text.Fusion.Internal (M(..), S(..))
import Data.Text.UnsafeChar (ord)
import Data.Text.UnsafeShift (shiftR)
import Data.Word (Word8)
import qualified Data.Text.Encoding.Utf8 as U8
Expand Down
24 changes: 19 additions & 5 deletions Data/Text/Encoding/Utf8.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE CPP, MagicHash #-}

-- |
-- Module : Data.Text.Encoding.Utf16
Expand Down Expand Up @@ -30,9 +30,11 @@ module Data.Text.Encoding.Utf8
, validate4
) where

#if defined(ASSERTS)
import Control.Exception (assert)
import Data.Char (ord)
#endif
import Data.Bits ((.&.))
import Data.Text.UnsafeChar (ord)
import Data.Text.UnsafeShift (shiftR)
import GHC.Exts
import GHC.Word (Word8(..))
Expand All @@ -47,22 +49,34 @@ between x y z = x >= y && x <= z
{-# INLINE between #-}

ord2 :: Char -> (Word8,Word8)
ord2 c = assert (n >= 0x80 && n <= 0x07ff) (x1,x2)
ord2 c =
#if defined(ASSERTS)
assert (n >= 0x80 && n <= 0x07ff)
#endif
(x1,x2)
where
n = ord c
x1 = fromIntegral $ (n `shiftR` 6) + 0xC0
x2 = fromIntegral $ (n .&. 0x3F) + 0x80

ord3 :: Char -> (Word8,Word8,Word8)
ord3 c = assert (n >= 0x0800 && n <= 0xffff) (x1,x2,x3)
ord3 c =
#if defined(ASSERTS)
assert (n >= 0x0800 && n <= 0xffff)
#endif
(x1,x2,x3)
where
n = ord c
x1 = fromIntegral $ (n `shiftR` 12) + 0xE0
x2 = fromIntegral $ ((n `shiftR` 6) .&. 0x3F) + 0x80
x3 = fromIntegral $ (n .&. 0x3F) + 0x80

ord4 :: Char -> (Word8,Word8,Word8,Word8)
ord4 c = assert (n >= 0x10000) (x1,x2,x3,x4)
ord4 c =
#if defined(ASSERTS)
assert (n >= 0x10000)
#endif
(x1,x2,x3,x4)
where
n = ord c
x1 = fromIntegral $ (n `shiftR` 18) + 0xF0
Expand Down
11 changes: 9 additions & 2 deletions Data/Text/Foreign.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BangPatterns, CPP #-}
-- |
-- Module : Data.Text.Foreign
-- Copyright : (c) Bryan O'Sullivan 2009
Expand All @@ -25,7 +25,9 @@ module Data.Text.Foreign
, unsafeCopyToPtr
) where

#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import Control.Monad.ST (unsafeIOToST)
import Data.Text.Internal (Text(..), empty)
import qualified Data.Text.Array as A
Expand Down Expand Up @@ -53,7 +55,11 @@ fromPtr :: Ptr Word16 -- ^ source array
-> Int -- ^ length of source array (in 'Word16' units)
-> IO Text
fromPtr _ 0 = return empty
fromPtr ptr len = assert (len > 0) $ return (Text arr 0 len)
fromPtr ptr len =
#if defined(ASSERTS)
assert (len > 0) $
#endif
return $! Text arr 0 len
where
arr = A.run (A.unsafeNew len >>= copy)
copy marr = loop ptr 0
Expand All @@ -68,6 +74,7 @@ fromPtr ptr len = assert (len > 0) $ return (Text arr 0 len)
-- 'unsafeCopyToPtr'.
lengthWord16 :: Text -> Int
lengthWord16 (Text _arr _off len) = len
{-# INLINE lengthWord16 #-}

-- | /O(n)/ Copy a 'Text' to an array. The array is assumed to be big
-- enough to hold the contents of the entire 'Text'.
Expand Down
3 changes: 1 addition & 2 deletions Data/Text/Fusion.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ import Prelude (Bool(..), Char, Maybe(..), Monad(..), Int,
Num(..), Ord(..), ($), (&&),
fromIntegral, otherwise)
import Data.Bits ((.&.))
import Data.Char (ord)
import Data.Text.Internal (Text(..))
import Data.Text.UnsafeChar (unsafeChr, unsafeWrite)
import Data.Text.UnsafeChar (ord, unsafeChr, unsafeWrite)
import Data.Text.UnsafeShift (shiftL, shiftR)
import qualified Data.Text.Array as A
import qualified Data.Text.Fusion.Common as S
Expand Down
15 changes: 13 additions & 2 deletions Data/Text/Fusion/Size.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
-- |
-- Module : Data.Text.Fusion.Internal
Expand Down Expand Up @@ -26,19 +27,29 @@ module Data.Text.Fusion.Size
, isEmpty
) where

#if defined(ASSERTS)
import Control.Exception (assert)
#endif

data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
| Max {-# UNPACK #-} !Int -- ^ Upper bound on size.
| Unknown -- ^ Unknown size.
deriving (Eq, Show)

exactSize :: Int -> Size
exactSize n = assert (n >= 0) Exact n
exactSize n =
#if defined(ASSERTS)
assert (n >= 0)
#endif
Exact n
{-# INLINE exactSize #-}

maxSize :: Int -> Size
maxSize n = assert (n >= 0) Max n
maxSize n =
#if defined(ASSERTS)
assert (n >= 0)
#endif
Max n
{-# INLINE maxSize #-}

unknownSize :: Size
Expand Down
20 changes: 12 additions & 8 deletions Data/Text/Internal.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE CPP, DeriveDataTypeable #-}

-- |
-- Module : Data.Text.Internal
Expand Down Expand Up @@ -28,7 +28,9 @@ module Data.Text.Internal
, showText
) where

#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import qualified Data.Text.Array as A
import Data.Typeable (Typeable)

Expand All @@ -42,13 +44,15 @@ data Text = Text
-- | Smart constructor.
text :: A.Array -> Int -> Int -> Text
text arr off len =
assert (len >= 0) .
assert (off >= 0) .
assert (alen == 0 || len == 0 || off < alen) .
assert (len == 0 || c < 0xDC00 || c > 0xDFFF) $
Text arr off len
where c = A.unsafeIndex arr off
alen = A.length arr
#if defined(ASSERTS)
let c = A.unsafeIndex arr off
alen = A.length arr
in assert (len >= 0) .
assert (off >= 0) .
assert (alen == 0 || len == 0 || off < alen) .
assert (len == 0 || c < 0xDC00 || c > 0xDFFF) $
#endif
Text arr off len
{-# INLINE text #-}

-- | /O(1)/ The empty 'Text'.
Expand Down
18 changes: 13 additions & 5 deletions Data/Text/Lazy/Builder.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE BangPatterns, Rank2Types #-}
{-# LANGUAGE BangPatterns, CPP, Rank2Types #-}

-----------------------------------------------------------------------------
-- |
Expand Down Expand Up @@ -29,7 +29,9 @@ module Data.Text.Lazy.Builder
, flush
) where

#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import Control.Monad.ST (ST, runST)
import Data.Bits ((.&.))
import Data.Char (ord)
Expand Down Expand Up @@ -259,8 +261,10 @@ newBuffer size = do
-- | Unsafely copy the elements of an array.
unsafeCopy :: A.Array -> Int -> A.MArray s -> Int -> Int -> ST s ()
unsafeCopy src sidx dest didx count =
#if defined(ASSERTS)
assert (sidx + count <= A.length src) .
assert (didx + count <= A.length dest) $
#endif
copy_loop sidx didx 0
where
copy_loop !i !j !c
Expand All @@ -274,12 +278,16 @@ unsafeCopy src sidx dest didx count =
unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
unsafeWrite marr i c
| n < 0x10000 = do
assert (i >= 0) . assert (i < A.length marr) $
A.unsafeWrite marr i (fromIntegral n)
#if defined(ASSERTS)
assert (i >= 0) . assert (i < A.length marr) $ return ()
#endif
A.unsafeWrite marr i (fromIntegral n)
return 1
| otherwise = do
assert (i >= 0) . assert (i < A.length marr - 1) $
A.unsafeWrite marr i lo
#if defined(ASSERTS)
assert (i >= 0) . assert (i < A.length marr - 1) $ return ()
#endif
A.unsafeWrite marr i lo
A.unsafeWrite marr (i+1) hi
return 2
where n = ord c
Expand Down
10 changes: 8 additions & 2 deletions Data/Text/Lazy/Encoding/Fusion.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE BangPatterns, Rank2Types #-}
{-# LANGUAGE BangPatterns, CPP, Rank2Types #-}

-- |
-- Module : Data.Text.Lazy.Encoding.Fusion
Expand Down Expand Up @@ -43,7 +43,9 @@ import System.IO.Unsafe (unsafePerformIO)
import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
import Foreign.Storable (pokeByteOff)
import Data.ByteString.Internal (mallocByteString, memcpy)
#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import qualified Data.ByteString.Internal as B

data S = S0
Expand Down Expand Up @@ -123,7 +125,11 @@ unstreamChunks chunkSize (Stream next s0 len0) = chunk s0 (upperBound 4 len0)
loop n' (off+1) s fp'
trimUp fp off = B.PS fp 0 off
copy0 :: ForeignPtr Word8 -> Int -> Int -> IO (ForeignPtr Word8)
copy0 !src !srcLen !destLen = assert (srcLen <= destLen) $ do
copy0 !src !srcLen !destLen =
#if defined(ASSERTS)
assert (srcLen <= destLen) $
#endif
do
dest <- mallocByteString destLen
withForeignPtr src $ \src' ->
withForeignPtr dest $ \dest' ->
Expand Down
Loading

0 comments on commit a99b318

Please sign in to comment.