# One Billion Row challenge in Hs

**URL:** <https://discourse.haskell.org/t/one-billion-row-challenge-in-hs/8946>\
**Category:** Links\
**Created:** [March 3, 2024, 8:24am UTC](https://discourse.haskell.org/t/one-billion-row-challenge-in-hs/8946 "2024-03-03T08:24:38Z")\
**Posts on this page:** 1\
**Showing post:** 108

<div class="post-metadata">

**Author:** ![ReleaseCandidate](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/releasecandidate/32/2849_2.png) [@ReleaseCandidate](https://discourse.haskell.org/u/ReleaseCandidate)\
**Post date:** [March 12, 2024, 9:22am UTC](https://discourse.haskell.org/t/one-billion-row-challenge-in-hs/8946/108 "2024-03-12T09:22:20Z")

</div>

Interestingly, even when adapting your solution to my program like below, `unsafeIndex` still is slower (by about 2s or 2%) than `uncons` like in the second version:

## unsafeIndex

```haskell
  let x1 = BSU.unsafeIndex rest2 0
  let x2 = BSU.unsafeIndex rest2 1
  let x3 = BSU.unsafeIndex rest2 2
  let x4 = BSU.unsafeIndex rest2 3
  let x5 = BSU.unsafeIndex rest2 4
  let (temp, rest) = case x1 of
        -- ord '-' == 45 => -N.N or -NN.N
        W8# 45#Word8 -> case x3 of
          -- ord '.' == 46 => -N.N
          W8# 46#Word8 -> (528 - fromIntegral x2 * 10 - fromIntegral x4, BS.drop 4 rest2)
          -- -NN.N
          _ -> (5328 - fromIntegral x2 * 100 - fromIntegral x3 * 10 - fromIntegral x5, BS.drop 5 rest2)
        -- N.N or NN.N
        _ -> case x2 of
          -- ord '.' == 46 => N.N
          W8# 46#Word8 -> (fromIntegral x1 * 10 + fromIntegral x3 - 528, BS.drop 3 rest2)
          -- NN.N
          _ -> (fromIntegral x1 * 100 + fromIntegral x2 * 10 + fromIntegral x4 - 5328, BS.drop 4 rest2)

```

```plaintext
hyperfine -w 1 -r 5 './exe-exe ../measurements.txt > solution.txt' 
Benchmark 1: ./exe-exe ../measurements.txt > solution.txt
  Time (mean ± σ): 99.749 s ± 0.512 s [User: 90.609 s, System: 20.358 s]
  Range (min … max): 99.099 s … 100.309 s 5 runs

```

## uncons

```haskell
{-# INLINE parseNegTemp #-}
parseNegTemp :: BS.ByteString -> (Int, BS.ByteString)
parseNegTemp rest = case BS.uncons rest of
  Nothing -> (0, rest)
  Just (ch1, rest3) -> case BS.uncons rest3 of
    Nothing -> (0, rest3)
    Just ('.', rest4) -> case BS.uncons rest4 of
      Nothing -> (0, rest4)
      Just (ch2, rest5) -> (528 - 10 * ord ch1 - ord ch2, rest5)
    Just (ch2, rest4) -> case BS.uncons rest4 of
      Nothing -> (0, rest4)
      -- Must be '.'
      Just (_, rest5) -> case BS.uncons rest5 of
        Nothing -> (0, rest5)
        Just (ch3, rest6) -> (5328 - 100 * ord ch1 - 10 * ord ch2 - ord ch3, rest6)

{-# INLINE parseTemp #-}
parseTemp :: Char -> BS.ByteString -> (Int, BS.ByteString)
parseTemp ch1 rest = case BS.uncons rest of
  Nothing -> (0, rest)
  Just ('.', rest4) -> case BS.uncons rest4 of
    Nothing -> (0, rest4)
    Just (ch2, rest5) -> (10 * ord ch1 + ord ch2 - 528, rest5)
  Just (ch2, rest4) -> case BS.uncons rest4 of
    Nothing -> (0, rest4)
    -- Must be '.'
    Just (_, rest5) -> case BS.uncons rest5 of
      Nothing -> (0, rest5)
      Just (ch3, rest6) -> (100 * ord ch1 + 10 * ord ch2 + ord ch3 - 5328, rest6)

```

```plaintext
hyperfine -w 1 -r 5 './exe-exe ../measurements.txt > solution.txt' 
Benchmark 1: ./exe-exe ../measurements.txt > solution.txt
  Time (mean ± σ): 97.509 s ± 0.695 s [User: 88.850 s, System: 17.293 s]
  Range (min … max): 96.692 s … 98.301 s 5 runs

```

> [@unhammer](#):
>
> There was a similar [optimisation thread](http://discourse.haskell.org/t/counting-words-but-can-we-go-faster/4864/30) here which ended up birthing two new hashmap packages

Interesting, thanks, will take a look!

---

_[View the full topic](https://discourse.haskell.org/t/one-billion-row-challenge-in-hs/8946)._
