Instantly share code, notes, and snippets.

@ndmitchell /Lib.c
Last active Dec 12, 2017

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