Skip to content

IntSet.fromList slower than repeated IntSet.insert #288

@amigalemming

Description

@amigalemming

I ran the following benchmark:

module Main where

import Criterion.Main (defaultMain, bgroup, bench, nf, )

import qualified Data.IntSet as IntSet; import Data.IntSet (IntSet)
import qualified Data.List as List
import Data.Word (Word64)


{-# INLINE randomIndices #-}
randomIndices :: Int -> [Int]
randomIndices k =
   map (fromIntegral . flip mod (fromIntegral k)) $
   iterate (\x -> mod (x*40692) 2147483399) (1::Word64)

constructIntSet :: Int -> Int -> IntSet
constructIntSet n k =
   IntSet.fromList $ take n $ randomIndices k

insertsIntSet :: Int -> Int -> IntSet
insertsIntSet n k =
   List.foldl' (flip IntSet.insert) IntSet.empty $
   take n $ randomIndices k


main :: IO ()
main =
   defaultMain $
      (bgroup "construct" $
         bench "1000" (nf (constructIntSet 500) 1000) :
         bench "3000" (nf (constructIntSet 500) 3000) :
         bench "9000" (nf (constructIntSet 500) 9000) :
         []) :
      (bgroup "insert" $
         bench "1000" (nf (insertsIntSet 500) 1000) :
         bench "3000" (nf (insertsIntSet 500) 3000) :
         bench "9000" (nf (insertsIntSet 500) 9000) :
         []) :
      []

and got:

benchmarking construct/1000
time                 53.36 μs   (53.24 μs .. 53.55 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 53.46 μs   (53.32 μs .. 53.73 μs)
std dev              638.6 ns   (367.6 ns .. 1.215 μs)

benchmarking construct/3000
time                 66.19 μs   (65.96 μs .. 66.54 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 66.21 μs   (66.09 μs .. 66.35 μs)
std dev              422.9 ns   (350.3 ns .. 547.7 ns)

benchmarking construct/9000
time                 81.97 μs   (81.67 μs .. 82.39 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 83.00 μs   (82.68 μs .. 83.29 μs)
std dev              1.052 μs   (914.6 ns .. 1.202 μs)

benchmarking insert/1000
time                 38.65 μs   (38.58 μs .. 38.79 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 38.90 μs   (38.80 μs .. 39.14 μs)
std dev              505.4 ns   (292.0 ns .. 1.066 μs)

benchmarking insert/3000
time                 47.91 μs   (47.53 μs .. 48.25 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 47.82 μs   (47.65 μs .. 48.02 μs)
std dev              626.2 ns   (518.8 ns .. 766.2 ns)

benchmarking insert/9000
time                 63.68 μs   (63.32 μs .. 64.21 μs)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 64.61 μs   (64.27 μs .. 65.01 μs)
std dev              1.230 μs   (959.5 ns .. 1.847 μs)
variance introduced by outliers: 14% (moderately inflated)

However, I am not sure whether I got the strictness right.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions