Skip to content

Instantly share code, notes, and snippets.

@Nnwww
Last active October 12, 2017 05:53
Show Gist options
  • Save Nnwww/e79ff5a252a5f54575da1e5aa3309175 to your computer and use it in GitHub Desktop.
Save Nnwww/e79ff5a252a5f54575da1e5aa3309175 to your computer and use it in GitHub Desktop.
naive sigmoid vs memorized sigmoid in Haskell
benchmarking sigmoid functions/naive
time 493.9 ms (467.9 ms .. 519.2 ms)
1.000 R² (0.999 R² .. 1.000 R²)
mean 490.2 ms (482.8 ms .. 493.5 ms)
std dev 6.459 ms (0.0 s .. 6.998 ms)
variance introduced by outliers: 19% (moderately inflated)
benchmarking sigmoid functions/SigTable
time 1.449 s (1.406 s .. 1.509 s)
1.000 R² (0.999 R² .. 1.000 R²)
mean 1.442 s (1.428 s .. 1.451 s)
std dev 13.47 ms (0.0 s .. 15.54 ms)
variance introduced by outliers: 19% (moderately inflated)
#!/usr/bin/env stack
{- stack --resolver lts-8.23 --install-ghc runghc
--package criterion --package vector
-}
{-# LANGUAGE StrictData #-}
import Criterion.Main
import qualified Data.Vector.Unboxed as VU
setupEnv = pure $ replicate 1000000 (1 :: Double)
main = defaultMain [
env setupEnv $ \ ~list -> bgroup "sigmoid functions"
[ bench "naive" $ nf (map sigmoid) list
, bench "SigTable" $ nf (map lookSigT) list
]
]
where
lookSigT = lookupSigTable sigt
sigt = initSigTable 512 8
sigmoid :: Double -> Double
sigmoid lx = 1.0 / (1.0 + exp (negate lx))
data SigTable = SigTable
{ sigTable :: {-# UNPACK #-} (VU.Vector Double)
, sigSize :: {-# UNPACK #-} Double
, sigMaxX :: {-# UNPACK #-} Double
}
initSigTable :: Int -> Double -> SigTable
initSigTable tableSize maxValue = SigTable
{sigTable = sigmoidTable, sigSize = floatingSize, sigMaxX = maxValue}
where
floatingSize = fromIntegral tableSize
sigmoidTable = VU.generate tableSize (lsigmoid . mapIndexToTableX . fromIntegral)
lsigmoid lx = 1.0 / (1.0 + exp (negate lx))
mapIndexToTableX idx = (idx * 2.0 * maxValue) / floatingSize - maxValue
lookupSigTable :: SigTable -> Double -> Double
lookupSigTable SigTable{sigTable = sigT, sigSize = size, sigMaxX = maxX} x
| x < -maxX = 0.0
| maxX < x = 1.0
| otherwise = sigT `VU.unsafeIndex` mapInputToIndex x
where
mapInputToIndex lx = floor ((lx + maxX) * size / maxX / 2.0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment