One Billion Row challenge in Hs

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

  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)
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

{-# 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)
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

Interesting, thanks, will take a look!

1 Like