Skip to content

Instantly share code, notes, and snippets.

@pete-murphy
Last active September 20, 2019 04:09
Show Gist options
  • Save pete-murphy/9a2b698e05f7a865ec208bd4ef932820 to your computer and use it in GitHub Desktop.
Save pete-murphy/9a2b698e05f7a865ec208bd4ef932820 to your computer and use it in GitHub Desktop.
{-# LANGUAGE TupleSections #-}
module Main where
import Criterion.Main
import Data.Char (toLower)
import Data.Function (on)
import Data.List (sort)
import Data.Map (fromListWith)
isAnagramOf :: String -> String -> Bool
isAnagramOf = (==) `on` (sort . fmap toLower)
isAnagramOf' :: String -> String -> Bool
isAnagramOf' = (==) `on` (freqs . fmap toLower)
where
freqs = fromListWith (+) . fmap (, 1)
main :: IO ()
main = do
everyWord <- lines <$> readFile "/usr/share/dict/words"
defaultMain
[ bench "anagrams, sort" $ nf (fmap $ isAnagramOf "banana") everyWord
, bench "anagrams, freqs" $ nf (fmap $ isAnagramOf' "banana") everyWord
]
@pete-murphy
Copy link
Author

pete-murphy commented Sep 20, 2019

I would think that isAnagramOf' would be more efficient than isAnagramOf (since freqs is O(n), and sort must be less efficient than that) but I consistently get similar benchmarks

benchmarking anagrams, sort
time                 159.6 ms   (155.9 ms .. 163.2 ms)
                     0.999 R²   (0.998 R² .. 1.000 R²)
mean                 154.8 ms   (152.7 ms .. 156.5 ms)
std dev              2.522 ms   (1.833 ms .. 3.416 ms)
variance introduced by outliers: 12% (moderately inflated)

benchmarking anagrams, freqs
time                 160.0 ms   (157.7 ms .. 161.5 ms)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 153.7 ms   (150.6 ms .. 155.5 ms)
std dev              3.155 ms   (1.622 ms .. 4.750 ms)
variance introduced by outliers: 12% (moderately inflated)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment