Skip to content

Commit 1863928

Browse files
authored
Allowed inlining for traverseWithIndex (#623)
* Allowed inlining for traverseWithIndex Switched NOINLINE to INLINE: - Ideally this would be INLINABLE, but that can't have phase controls - This is the next best, which gets the proper performance benefits and also the phase controles so the rewrite rules still fire properly Because this was prompted by sequenceA.mapWithIndex being faster, a benchamrk of that operation has been added to compare. * INLINABLE can have phase controls As it turns out, INLINABLE *can* have phase controls. Benchmarks so no real change: benchmarking traverseWithIndex/State/10 time 368.6 ns (364.2 ns .. 372.2 ns) 0.999 R² (0.999 R² .. 1.000 R²) mean 366.6 ns (363.2 ns .. 370.0 ns) std dev 11.56 ns (9.593 ns .. 14.54 ns) variance introduced by outliers: 46% (moderately inflated) benchmarking traverseWithIndex/State/100 time 4.730 μs (4.663 μs .. 4.796 μs) 0.999 R² (0.998 R² .. 0.999 R²) mean 4.702 μs (4.660 μs .. 4.752 μs) std dev 149.9 ns (123.3 ns .. 192.9 ns) variance introduced by outliers: 40% (moderately inflated) benchmarking traverseWithIndex/State/1000 time 65.15 μs (64.31 μs .. 66.13 μs) 0.999 R² (0.998 R² .. 0.999 R²) mean 66.58 μs (65.80 μs .. 67.65 μs) std dev 3.082 μs (2.343 μs .. 4.561 μs) variance introduced by outliers: 50% (moderately inflated) benchmarking sequenceA.mapWithIndex/State/10 time 597.8 ns (589.4 ns .. 606.8 ns) 0.998 R² (0.997 R² .. 0.999 R²) mean 602.1 ns (595.9 ns .. 610.4 ns) std dev 23.84 ns (17.59 ns .. 38.02 ns) variance introduced by outliers: 56% (severely inflated) benchmarking sequenceA.mapWithIndex/State/100 time 5.915 μs (5.854 μs .. 6.023 μs) 0.998 R² (0.997 R² .. 0.999 R²) mean 6.006 μs (5.939 μs .. 6.078 μs) std dev 235.9 ns (199.3 ns .. 285.5 ns) variance introduced by outliers: 50% (moderately inflated) benchmarking sequenceA.mapWithIndex/State/1000 time 83.08 μs (81.80 μs .. 84.81 μs) 0.998 R² (0.998 R² .. 0.999 R²) mean 83.78 μs (83.04 μs .. 84.50 μs) std dev 2.604 μs (2.277 μs .. 3.018 μs) variance introduced by outliers: 30% (moderately inflated) * put INLINABLE behind a macro
1 parent 121df4a commit 1863928

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

Data/Sequence/Internal.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2975,7 +2975,12 @@ traverseWithIndex f' (Seq xs') = Seq <$> traverseWithIndexTreeE (\s (Elem a) ->
29752975
!sPsab = sPsa + size b
29762976

29772977

2978-
{-# NOINLINE [1] traverseWithIndex #-}
2978+
#ifdef __GLASGOW_HASKELL__
2979+
{-# INLINABLE [1] traverseWithIndex #-}
2980+
#else
2981+
{-# INLINE [1] traverseWithIndex #-}
2982+
#endif
2983+
29792984
#ifdef __GLASGOW_HASKELL__
29802985
{-# RULES
29812986
"travWithIndex/mapWithIndex" forall f g xs . traverseWithIndex f (mapWithIndex g xs) =

benchmarks/Sequence.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ main = do
9090
, bench "100" $ nf multiplyDown s100
9191
, bench "1000" $ nf multiplyDown s1000
9292
]
93+
, bgroup "sequenceA.mapWithIndex/State"
94+
[ bench "10" $ nf multiplyDownMap s10
95+
, bench "100" $ nf multiplyDownMap s100
96+
, bench "1000" $ nf multiplyDownMap s1000
97+
]
9398
, bgroup "traverse/State"
9499
[ bench "10" $ nf multiplyUp s10
95100
, bench "100" $ nf multiplyUp s100
@@ -242,3 +247,10 @@ multiplyDown = flip evalState 0 . S.traverseWithIndex go where
242247
s <- get
243248
put (s - 1)
244249
return (s * i * x)
250+
251+
multiplyDownMap :: S.Seq Int -> S.Seq Int
252+
multiplyDownMap = flip evalState 0 . sequenceA . S.mapWithIndex go where
253+
go i x = do
254+
s <- get
255+
put (s - 1)
256+
return (s * i * x)

0 commit comments

Comments
 (0)