Here we go, Data.Vector and the same somewhat flawed comparison as in the post:
next a = Just . join (,) $ (if even a then a else 3*a+1) `div` 2
len = (+1) . V.length . V.takeWhile (/=1) . V.unfoldr next
result = V.maximum . V.map (\x -> (len x, x)) . V.enumFromTo 1
main = do [a0] <- getArgs
let max_a0 = read a0 :: Word32
print . result $ max_a0
Results: haskell 5.0s, C 4.8s. Good enough I guess?
PS: and this is how you do a proper benchmarking:
import Criterion.Main
main = defaultMain [
bench "data.vector/1M" $ whnf result 10000000
]
resultQ :: W -> (W,W)
resultQ n = foldAllS max (0,0) $ runIdentity $ R.computeUnboxedP vec
where
fun (Z :. i) = len &&& id $ fromIntegral i
vec = R.fromFunction (Z :. fromIntegral n) fun :: Array D DIM1 (W,W)
PS: and this is how you do a proper benchmarking:
with result like http://lelf.lu/tmp/criterion.html