Skip to content

Instantly share code, notes, and snippets.

@ndmitchell ndmitchell/Lib.c
Last active May 2, 2019

Embed
What would you like to do?
memchr vs strchr

To compile and run:

# Get Haskell/Cabal
cabal update && cabal install criterion
gcc -c -O3 Lib.c
ghc Main.hs Lib.o
./Main
#include <stddef.h>
// From http://clc-wiki.net/wiki/strchr
char *strchr_c(const char *s, int c)
{
while (*s != (char)c)
if (!*s++)
return 0;
return (char *)s;
}
// From http://clc-wiki.net/wiki/memchr
void *memchr_c(const void *s, int c, size_t n)
{
unsigned char *p = (unsigned char*)s;
while( n-- )
if( *p != (unsigned char)c )
p++;
else
return p;
return 0;
}
import qualified Data.ByteString as BS
import qualified Data.ByteString.Unsafe as BS
import Criterion.Main
import Foreign
import Foreign.C.Types
import System.IO.Unsafe
import Data.Monoid
foreign import ccall unsafe "string.h memchr" memchr_std :: Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)
foreign import ccall unsafe "string.h strchr" strchr_std :: Ptr Word8 -> CInt -> IO (Ptr Word8)
foreign import ccall unsafe memchr_c :: Ptr Word8 -> CInt -> CSize -> IO (Ptr Word8)
foreign import ccall unsafe strchr_c :: Ptr Word8 -> CInt -> IO (Ptr Word8)
ignoreSize f a b _ = f a b
cstr i = BS.replicate i 32 <> BS.singleton 64 <> BS.replicate i 32 <> BS.singleton 0
funs =
[("memchr_std", memchr_std)
,("strchr_std", ignoreSize strchr_std)
,("memchr_c", memchr_c)
,("strchr_c", ignoreSize strchr_c)]
main = defaultMain
[ seq bs $ bench (show i ++ " " ++ name) $ whnfIO $ test fun bs
| i <- [1,10,100,1000,10000,100000,1000000,10000000]
, let bs = cstr i
, (name, fun) <- funs]
{-# NOINLINE test #-}
test fun bs =
BS.unsafeUseAsCStringLen bs $ \(ptr,len) ->
fun (castPtr ptr) 64 (fromIntegral len)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.