[Haskell-cafe] hstats median algorithm

Felipe Almeida Lessa felipe.lessa at gmail.com
Mon Sep 3 16:18:30 CEST 2012


Some comments wrt. performance:

On Mon, Sep 3, 2012 at 9:57 AM,  <timothyhobbs at seznam.cz> wrote:
>>  Right (medianBucket,stubLen) =
>>   foldr
>>    (\thisBucket@(thisBucketLen,_) eitheriOrMedianBucket ->
>>     case eitheriOrMedianBucket of
>>      Left i ->
>>       if i + thisBucketLen > (length `div` 2)
>>        then Right (thisBucket, thisBucketLen-((length `div` 2) - i))
>>        else Left (i + thisBucketLen)
>>      _ -> eitheriOrMedianBucket)
>>    (Left 0)
>>    myBuckets

Use a let to store length `div` 2, GHC probably won't do this for you
automatically.  Ditto for i + thisBucketLen.

>>  buckets' <- mapM
>>               (\n->
>>                 newSTRef
>>                   (0,
>>                    if n >= guessedMiddleStart && n <= guessedMiddleEnd
>>                      then Just []
>>                      else Nothing))
>>               [0..numBuckets]

You should really use a mutable array here instead of a list of STRefs
(I recommend vector's STVector [1]).

[1] http://hackage.haskell.org/packages/archive/vector/0.9.1/doc/html/Data-Vector-Mutable.html

> Increment length.
>
>>    modifySTRef
>>     lengthRef
>>     (+1)

This will create a big thunk for the length, you should use

  oldLength <- readSTRef lengthRef
  writeSTRef lengthRef $! oldLength + 1

(I'm not sure if a strict modifySTRef exists somewhere...)

> Put the value into the appropriate bucket.
>
>>    modifySTRef
>>     (buckets' `genericIndex` bucket) --Obvious optimization, use an array
>> and not a list.
>>     (\(oldLen,oldListMaybe)->
>>       case oldListMaybe of
>>        Just oldList ->
>>         (oldLen+1,Just (number:oldList))
>>        Nothing -> (oldLen + 1, Nothing))

Ditto for oldLen here.  Also, you can simplify this lambda a lot:

  import Control.Applicative ((<$>))

  \(oldLen, oldVal) ->
    let newLen = oldLen + 1
        newVal = (number:) <$> oldVal
    in newLen `seq` newVal `seq` (newLen, newVal)

HTH!

Cheers,

-- 
Felipe.



More information about the Haskell-Cafe mailing list