Skip to content

Instantly share code, notes, and snippets.

@tfausak
tfausak / _README.markdown
Last active January 17, 2018 14:15
Benchmark of various containers doing bit-level manipulation.

I'm back with more bit-level benchmarks in Haskell. The goal here is to do some work on each bit in a large string of bytes. The time to beat is about 5 ms, which is how long Rust takes to do this. Unfortunately it looks like Haskell isn't quite up to the task:

Type Time
ByteString 483.8 ms
Vector Bool (boxed) 315.9 ms
Vector Word8 (boxed) 500.3 ms
0008: Decoded 0.090 MB in 156.435 ms at 0.575 MB/s
000b: Decoded 0.356 MB in 411.709 ms at 0.864 MB/s
07e9: Decoded 0.029 MB in 20.839 ms at 1.376 MB/s
0ad2: Decoded 0.027 MB in 17.437 ms at 1.529 MB/s
1205: Decoded 0.440 MB in 624.863 ms at 0.704 MB/s
160c: Decoded 0.539 MB in 685.560 ms at 0.786 MB/s
16d5: Decoded 0.029 MB in 20.244 ms at 1.446 MB/s
18d6: Decoded 0.021 MB in 14.670 ms at 1.430 MB/s
1a12: Decoded 0.094 MB in 77.999 ms at 1.208 MB/s
1ae4: Decoded 0.025 MB in 17.057 ms at 1.450 MB/s
Type Time (ns)
[Bool] 65060000
[Word8] 12520000
Vector Word8 186800
U.Vector Word8 183200
ByteString 176300
Vector Bool 92630
U.Vector Bool 86580
@tfausak
tfausak / _results.md
Last active January 11, 2018 17:22
Benchmarking CRC32 in Haskell and Rust for Rocket League.

I am the maintainer of Rattletrap, a Rocket League replay parser written in Haskell. Recently I became aware of @nickbabcock's Boxcars project, which is also a Rocket League replay parser but it's written in Rust. I generally think of Haskell as Fast Enough ™️ for a high-level language. I was curious to see how much faster Rust would be for this particular application. You can see some casual benchmarks here: nickbabcock/boxcars#6.

This Gist benchmarks four basic operations in both Haskell and Rust. I am a Haskell programmer and want to see it triumph, but it turns out Rust is at least an order of magnitude faster in these benchmarks. However, in the benchmark that actuall does something (the CRC benchmark), Haskell and Rust are within one millisecond of each other. If you think there are any problems with the benchmark, please let me know.

-- stack --resolver lts-10.0 script
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
import qualified Data.Aeson as Json
import Data.Aeson.Encode.Pretty (encodePretty)
import Data.ByteString (ByteString)
import Data.ByteString.Lazy (writeFile)
import Data.Colour.SRGB (sRGB24)
import qualified Data.CSV.Conduit as Csv
import qualified Data.CSV.Conduit.Conversion as Csv
@tfausak
tfausak / xml-lens.hs
Created December 12, 2017 04:00
XML lenses have stumped me.
-- stack --resolver nightly-2017-12-01 script
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text.Lazy.IO as LazyText
import Text.XML
import Text.XML.Lens
main :: IO ()
main = do
let original = parseText_ def "<root> <old>1</old> <old>2</old> </root>"
@tfausak
tfausak / haddock.hs
Created December 8, 2017 23:17
Some examples of weird Haddock behavior.
import Prelude hiding (id, mod, (+))
import qualified Documentation.Haddock.Parser as Haddock
import qualified Documentation.Haddock.Types as Haddock
main :: IO ()
main = runTests
--
-- problems
# The GHC team announced the second release candidate for the 8.2.2 release of
# GHC: https://mail.haskell.org/pipermail/ghc-devs/2017-October/014994.html
#
# This is an example `stack.yaml` file that you can use to try out the release
# candidate. Save this file in your current directory and run `stack setup`.
# After that you should be able to use Stack as normal, including
# `stack exec ghci` and `stack build`.
#
# If for whatever reason you don't want to use Stack, you can download the
# official release tarballs at: https://downloads.haskell.org/~ghc/8.2.2-rc2/
-- This is a small benchmark meant to see how fast the http-client library can
-- make requests. In particular, it's meant to compare the network library and
-- the socket library. <https://github.com/snoyberg/http-client/pull/306>
import qualified Control.Concurrent.Async as Async
import qualified Control.Monad as Monad
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Text.Lazy as LazyText
import qualified Data.Text.Lazy.Encoding as LazyText
#!/usr/bin/env node
'use strict';
// This is a little JavaScript utility meant to be used with Rattletrap to
// reduce the size of Rocket League replay files. See this issue for more:
// <https://github.com/tfausak/rattletrap/issues/49>. Example usage:
//
// $ stack exec rattletrap decode < original.replay > original.json
// $ node strip-replay.js < original.json > stripped.json
// $ stack exec rattletrap encode < stripped.json > stripped.replay