this post was submitted on 17 Aug 2023
2 points (100.0% liked)

Haskell

5 readers
1 users here now

**The Haskell programming language community.** Daily news and info about all things Haskell related: practical stuff, theory, types, libraries, jobs, patches, releases, events and conferences and more... ### Links - Get Started with Haskell

founded 2 years ago
 

Consider the following two implementations of a 'map' function for arrays. Can you guess which one of them is the fastest without running them? (Please ignore the uses of unsafeCoerce :P)

Required imports:

import Data.Primitive.Array
import Control.Monad.ST.Strict
import Unsafe.Coerce

Version 1:

mapArray1 :: forall a b. (a -> b) -> Array a -> Array b
mapArray1 f arr = runST $
  let n = length arr in
  thawArray arr 0 n >>= \m ->
  let
    go i
      | i < n = do
        x <- readArray m i
        writeArray m i $! unsafeCoerce @b @a (f x)
        go (i + 1)
      | otherwise = do
        arr' <- unsafeFreezeArray m
        return (unsafeCoerce @(Array a) @(Array b) arr')
  in
    go 0

Version 2:

mapArray2 :: forall a b. (a -> b) -> Array a -> Array b
mapArray2 f arr =
  let n = length arr in
  createArray n (unsafeCoerce @() @b ()) $ \m ->
    let
      go i
        | i < n = do
          writeArray m i $! f $! indexArray arr i
          go (i + 1)
        | otherwise = return ()
    in
      go 0

you are viewing a single comment's thread
view the rest of the comments
[โ€“] jaror@kbin.social 1 points 2 years ago (1 children)

I've spent this evening trying to get conclusive benchmark results, but I have not succeeded with that yet. It seems like this is pretty difficult to benchmark. So I'd like to hear it if someone else is able to get good benchmark results.

[โ€“] jaror@kbin.social 1 points 2 years ago

I'm getting pretty consistent results like this now.