module Main where import Data.Char import Test.Tasty.Bench import qualified Control.Lens as L import qualified Control.Lens.Unsound as L import qualified Control.Monad.Trans.State as S import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString.Lazy.Char8 as BSL8 import qualified Data.ByteString.Lens as L import qualified Data.HashMap.Strict as HM import qualified Data.IntMap as IM import qualified Data.Map as M import qualified Data.Sequence as S import qualified Data.Vector as V import qualified Data.Vector.Unboxed as U import Data.ByteString.Optics import Optics main :: IO () main = defaultMain [ bgroup "vector" [ bgroup "traverse" [ bench "native" $ nf (\x -> S.execState (traverse (S.modify' . (+)) x) 0) v , bench "each" $ nf (\x -> S.execState (traverseOf each (S.modify' . (+)) x) 0) v , bench "each/lens" $ nf (\x -> S.execState (L.traverseOf L.each (S.modify' . (+)) x) 0) v , bench "itraversed" $ nf (\x -> S.execState (traverseOf itraversed (S.modify' . (+)) x) 0) v , bench "itraversed/lens" $ nf (\x -> S.execState (L.traverseOf L.itraversed (S.modify' . (+)) x) 0) v ] , bgroup "itraverse" [ bench "native" $ nf (\x -> S.execState (traverse (\(i, a) -> S.modify' $ (i + a +)) $ V.indexed x) 0) v , bench "itraverse" $ nf (\x -> S.execState (itraverse (\i a -> S.modify' $ (i + a +)) x) 0) v , bench "itraverse/lens" $ nf (\x -> S.execState (L.itraverse (\i a -> S.modify' $ (i + a +)) x) 0) v , bench "each" $ nf (\x -> S.execState (itraverseOf each (\i a -> S.modify' $ (i + a +)) x) 0) v , bench "itraversed" $ nf (\x -> S.execState (itraverseOf itraversed (\i a -> S.modify' $ (i + a +)) x) 0) v , bench "itraversed/lens" $ nf (\x -> S.execState (L.itraverseOf L.itraversed (\i a -> S.modify' $ (i + a +)) x) 0) v ] , bgroup "map" [ bench "native" $ nf (V.map (+100)) v , bench "each" $ nf (over each (+100)) v , bench "each/lens" $ nf (L.over L.each (+100)) v , bench "itraversed" $ nf (over itraversed (+100)) v , bench "itraversed/lens" $ nf (L.over L.itraversed (+100)) v , bench "imapped" $ nf (over imapped (+100)) v , bench "imapped/lens" $ nf (L.over L.imapped (+100)) v ] , bgroup "imap" [ bench "native" $ nf (V.imap (\i x -> x + i +100)) v , bench "imap" $ nf (imap (\i x -> x + i +100)) v , bench "imap/lens" $ nf (L.imap (\i x -> x + i +100)) v , bench "each" $ nf (iover each (\i x -> x + i +100)) v , bench "itraversed" $ nf (iover itraversed (\i x -> x + i +100)) v , bench "itraversed/lens" $ nf (L.iover L.itraversed (\i x -> x + i +100)) v , bench "imapped" $ nf (iover imapped (\i x -> x + i +100)) v , bench "imapped/lens" $ nf (L.iover L.imapped (\i x -> x + i +100)) v ] , bgroup "elements" [ bench "itraversed" $ nf (iover itraversed (+)) v , bench "itraversed/lens" $ nf (L.iover L.itraversed (+)) v , bench "elements" $ nf (iover (elements $ const True) (+)) v , bench "elements/lens" $ nf (L.iover (L.elements $ const True) (+)) v ] , bgroup "partsOf" [ bench "partsOf" $ nf (over (partsOf traversed) reverse) v , bench "partsOf/lens" $ nf (L.over (L.partsOf traverse) reverse) v , bench "ipartsOf" $ nf (iover (ipartsOf itraversed) (\is -> reverse . zipWith (+) is)) v , bench "ipartsOf/lens" $ nf (L.iover (L.ipartsOf L.itraversed) (\is -> reverse . zipWith (+) is)) v ] , bgroup "singular" [ bench "singular" $ nf (over (singular traversed) id) v , bench "singular/lens" $ nf (L.over (L.singular traverse) id) v ] , bgroup "indices" [ bench "indices" $ nf (iover (itraversed %& indices even) (+)) v , bench "indices/lens" $ nf (L.iover (L.itraversed . L.indices even) (+)) v ] ] , bgroup "unboxed-vector" [ bgroup "map" [ bench "native" $ nf (U.map (+100)) u , bench "each" $ nf (over each (+100)) u , bench "each/lens" $ nf (L.over L.each (+100)) u ] , bgroup "imap" [ bench "native" $ nf (U.imap (\i x -> x + i +100)) u , bench "each" $ nf (iover each (\i x -> x + i)) u ] ] , bgroup "sequence" [ bgroup "traverse" [ bench "native" $ nf (\x -> S.execState (traverse (S.modify' . (+)) x) 0) s , bench "each" $ nf (\x -> S.execState (traverseOf each (S.modify' . (+)) x) 0) s , bench "each/lens" $ nf (\x -> S.execState (L.traverseOf L.each (S.modify' . (+)) x) 0) s , bench "itraversed" $ nf (\x -> S.execState (traverseOf itraversed (S.modify' . (+)) x) 0) s , bench "itraversed/lens" $ nf (\x -> S.execState (L.traverseOf L.itraversed (S.modify' . (+)) x) 0) s ] , bgroup "itraverse" [ bench "native" $ nf (\x -> S.execState (S.traverseWithIndex (\i a -> S.modify' $ (i + a +)) x) 0) s , bench "itraverse " $ nf (\x -> S.execState (itraverse (\i a -> S.modify' $ (i + a +)) x) 0) s , bench "itraverse/lens" $ nf (\x -> S.execState (L.itraverse (\i a -> S.modify' $ (i + a +)) x) 0) s , bench "each" $ nf (\x -> S.execState (itraverseOf each (\i a -> S.modify' $ (i + a +)) x) 0) s , bench "itraversed" $ nf (\x -> S.execState (itraverseOf itraversed (\i a -> S.modify' $ (i + a +)) x) 0) s , bench "itraversed/lens" $ nf (\x -> S.execState (L.itraverseOf L.itraversed (\i a -> S.modify' $ (i + a +)) x) 0) s ] , bgroup "map" [ bench "native" $ nf (fmap (+100)) s , bench "each" $ nf (over each (+100)) s , bench "each/lens" $ nf (L.over L.each (+100)) s , bench "itraversed" $ nf (over itraversed (+100)) s , bench "itraversed/lens" $ nf (L.over L.itraversed (+100)) s , bench "imapped" $ nf (over imapped (+100)) s , bench "imapped/lens" $ nf (L.over L.imapped (+100)) s ] , bgroup "imap" [ bench "native" $ nf (S.mapWithIndex (\i x -> x + i +100)) s , bench "imap" $ nf (imap (\i x -> x + i +100)) s , bench "imap/lens" $ nf (L.imap (\i x -> x + i +100)) s , bench "each" $ nf (iover each (\i x -> x + i +100)) s , bench "itraversed" $ nf (iover itraversed (\i x -> x + i +100)) s , bench "itraversed/lens" $ nf (L.iover L.itraversed (\i x -> x + i +100)) s , bench "imapped" $ nf (iover imapped (\i x -> x + i +100)) s , bench "imapped/lens" $ nf (L.iover L.imapped (\i x -> x + i +100)) s ] , bgroup "elements" [ bench "itraversed" $ nf (iover itraversed (+)) s , bench "itraversed/lens" $ nf (L.iover L.itraversed (+)) s , bench "elements" $ nf (iover (elements $ const True) (+)) s , bench "elements/lens" $ nf (L.iover (L.elements $ const True) (+)) s ] , bgroup "partsOf" [ bench "partsOf" $ nf (over (partsOf traversed) reverse) s , bench "partsOf/lens" $ nf (L.over (L.partsOf traverse) reverse) s , bench "ipartsOf" $ nf (iover (ipartsOf itraversed) (\is -> reverse . zipWith (+) is)) s , bench "ipartsOf/lens" $ nf (L.iover (L.ipartsOf L.itraversed) (\is -> reverse . zipWith (+) is)) s ] , bgroup "singular" [ bench "singular" $ nf (over (singular traversed) id) s , bench "singular/lens" $ nf (L.over (L.singular traverse) id) s ] , bgroup "indices" [ bench "indices" $ nf (iover (itraversed %& indices even) (+)) s , bench "indices/lens" $ nf (L.iover (L.itraversed . L.indices even) (+)) s ] ] , bgroup "bytestring" [ bgroup "map" [ bench "native" $ nf (BS.map (+100)) b , bench "each" $ nf (over each (+100)) b , bench "each/lens" $ nf (L.over L.each (+100)) b ] , bgroup "imap" [ bench "bytes" $ nf (iover bytes (\i x -> x + fromIntegral i)) b , bench "bytes/lens" $ nf (L.iover L.bytes (\i x -> x + fromIntegral i)) b ] ] , bgroup "bytestring char8" [ bgroup "map" [ bench "native" $ nf (BS8.map (chr . (+100) . ord)) b , bench "chars" $ nf (over chars (chr . (+100) . ord)) b , bench "chars/lens" $ nf (L.over L.chars (chr . (+100) . ord)) b ] , bgroup "imap" [ bench "chars" $ nf (iover chars (\i x -> chr $ ord x + fromIntegral (i `mod` 256))) b , bench "chars/lens" $ nf (L.iover L.chars (\i x -> chr $ ord x + fromIntegral (i `mod` 256))) b ] ] , bgroup "bytestring lazy" [ bgroup "map" [ bench "native" $ nf (BSL.map (+100)) bl , bench "each" $ nf (over each (+100)) bl , bench "each/lens" $ nf (L.over L.each (+100)) bl ] , bgroup "imap" [ bench "bytes" $ nf (iover bytes (\i x -> x + fromIntegral i)) bl , bench "bytes/lens" $ nf (L.iover L.bytes (\i x -> x + fromIntegral i)) bl ] ] , bgroup "bytestring lazy char8" [ bgroup "map" [ bench "native" $ nf (BSL8.map (chr . (+100) . ord)) bl , bench "chars" $ nf (over chars (chr . (+100) . ord)) bl , bench "chars/lens" $ nf (L.over L.chars (chr . (+100) . ord)) bl ] , bgroup "imap" [ bench "chars" $ nf (iover chars (\i x -> chr $ ord x + fromIntegral (i `mod` 256))) bl , bench "chars/lens" $ nf (L.iover L.chars (\i x -> chr $ ord x + fromIntegral (i `mod` 256))) bl ] ] , bgroup "list" [ bgroup "traverse" [ bench "native" $ nf (\x -> S.execState (traverse (S.modify' . (+)) x) 0) l , bench "each" $ nf (\x -> S.execState (traverseOf each (S.modify' . (+)) x) 0) l , bench "each/lens" $ nf (\x -> S.execState (L.traverseOf L.each (S.modify' . (+)) x) 0) l , bench "itraversed" $ nf (\x -> S.execState (traverseOf itraversed (S.modify' . (+)) x) 0) l , bench "itraversed/lens" $ nf (\x -> S.execState (L.traverseOf L.itraversed (S.modify' . (+)) x) 0) l ] , bgroup "itraverse" [ bench "native" $ nf (\x -> S.execState (traverse (\(i, a) -> S.modify' $ (i + a +)) (zip [0..] x)) 0) l , bench "itraverse" $ nf (\x -> S.execState (itraverse (\i a -> S.modify' $ (i + a +)) x) 0) l , bench "itraverse/lens" $ nf (\x -> S.execState (L.itraverse (\i a -> S.modify' $ (i + a +)) x) 0) l , bench "each" $ nf (\x -> S.execState (itraverseOf each (\i a -> S.modify' $ (i + a +)) x) 0) l , bench "itraversed" $ nf (\x -> S.execState (itraverseOf itraversed (\i a -> S.modify' $ (i + a +)) x) 0) l , bench "itraversed/lens" $ nf (\x -> S.execState (L.itraverseOf L.itraversed (\i a -> S.modify' $ (i + a +)) x) 0) l ] , bgroup "map" [ bench "native" $ nf (map (+100)) l , bench "each" $ nf (over each (+100)) l , bench "each/lens" $ nf (L.over L.each (+100)) l , bench "itraversed" $ nf (over itraversed (+100)) l , bench "itraversed/lens" $ nf (L.over L.itraversed (+100)) l , bench "imapped" $ nf (over imapped (+100)) l , bench "imapped/lens" $ nf (L.over L.imapped (+100)) l ] , bgroup "imap" [ bench "imap" $ nf (imap (\i x -> x + i +100)) l , bench "imap/lens" $ nf (L.imap (\i x -> x + i +100)) l , bench "each" $ nf (iover each (\i x -> x + i +100)) l , bench "itraversed" $ nf (iover itraversed (\i x -> x + i +100)) l , bench "itraversed/lens" $ nf (L.iover L.itraversed (\i x -> x + i +100)) l , bench "imapped" $ nf (iover imapped (\i x -> x + i +100)) l , bench "imapped/lens" $ nf (L.iover L.imapped (\i x -> x + i +100)) l ] , bgroup "elements" [ bench "itraversed" $ nf (iover itraversed (+)) l , bench "itraversed/lens" $ nf (L.iover L.itraversed (+)) l , bench "elements" $ nf (iover (elements $ const True) (+)) l , bench "elements/lens" $ nf (L.iover (L.elements $ const True) (+)) l ] , bgroup "partsOf" [ bench "partsOf" $ nf (over (partsOf traversed) reverse) l , bench "partsOf/lens" $ nf (L.over (L.partsOf traverse) reverse) l , bench "ipartsOf" $ nf (iover (ipartsOf itraversed) (\is -> reverse . zipWith (+) is)) l , bench "ipartsOf/lens" $ nf (L.iover (L.ipartsOf L.itraversed) (\is -> reverse . zipWith (+) is)) l ] , bgroup "singular" [ bench "singular" $ nf (over (singular traversed) id) l , bench "singular/lens" $ nf (L.over (L.singular traverse) id) l ] , bgroup "indices" [ bench "indices" $ nf (iover (itraversed %& indices even) (+)) l , bench "indices/lens" $ nf (L.iover (L.itraversed . L.indices even) (+)) l ] ] , bgroup "intmap" [ bgroup "traverse" [ bench "native" $ nf (\x -> S.execState (traverse (S.modify' . (+)) x) 0) im , bench "each" $ nf (\x -> S.execState (traverseOf each (S.modify' . (+)) x) 0) im , bench "each/lens" $ nf (\x -> S.execState (L.traverseOf L.each (S.modify' . (+)) x) 0) im , bench "itraversed" $ nf (\x -> S.execState (traverseOf itraversed (S.modify' . (+)) x) 0) im , bench "itraversed/lens" $ nf (\x -> S.execState (L.traverseOf L.itraversed (S.modify' . (+)) x) 0) im ] , bgroup "itraverse" [ bench "native" $ nf (\x -> S.execState (IM.traverseWithKey (\i a -> S.modify' $ (i + a +)) x) 0) im , bench "itraverse" $ nf (\x -> S.execState (itraverse (\i a -> S.modify' $ (i + a +)) x) 0) im , bench "itraverse/lens" $ nf (\x -> S.execState (L.itraverse (\i a -> S.modify' $ (i + a +)) x) 0) im , bench "each" $ nf (\x -> S.execState (itraverseOf each (\i a -> S.modify' $ (i + a +)) x) 0) im , bench "itraversed" $ nf (\x -> S.execState (itraverseOf itraversed (\i a -> S.modify' $ (i + a +)) x) 0) im , bench "itraversed/lens" $ nf (\x -> S.execState (L.itraverseOf L.itraversed (\i a -> S.modify' $ (i + a +)) x) 0) im ] , bgroup "map" [ bench "native" $ nf (fmap (+100)) im , bench "each" $ nf (over each (+100)) im , bench "each/lens" $ nf (L.over L.each (+100)) im , bench "itraversed" $ nf (over itraversed (+100)) im , bench "itraversed/lens" $ nf (L.over L.itraversed (+100)) im , bench "imapped" $ nf (over imapped (+100)) im , bench "imapped/lens" $ nf (L.over L.imapped (+100)) im ] , bgroup "imap" [ bench "native" $ nf (IM.mapWithKey (\i x -> x + i +100)) im , bench "imap" $ nf (imap (\i x -> x + i +100)) im , bench "imap/lens" $ nf (L.imap (\i x -> x + i +100)) im , bench "each" $ nf (iover each (\i x -> x + i +100)) im , bench "itraversed" $ nf (iover itraversed (\i x -> x + i +100)) im , bench "itraversed/lens" $ nf (L.iover L.itraversed (\i x -> x + i +100)) im , bench "imapped" $ nf (iover imapped (\i x -> x + i +100)) im , bench "imapped/lens" $ nf (L.iover L.imapped (\i x -> x + i +100)) im ] , bgroup "elements" [ bench "itraversed" $ nf (iover itraversed (+)) im , bench "itraversed/lens" $ nf (L.iover L.itraversed (+)) im , bench "elements" $ nf (iover (elements $ const True) (+)) im , bench "elements/lens" $ nf (L.iover (L.elements $ const True) (+)) im ] , bgroup "partsOf" [ bench "partsOf" $ nf (over (partsOf traversed) reverse) im , bench "partsOf/lens" $ nf (L.over (L.partsOf traverse) reverse) im , bench "ipartsOf" $ nf (iover (ipartsOf itraversed) (\is -> reverse . zipWith (+) is)) im , bench "ipartsOf/lens" $ nf (L.iover (L.ipartsOf L.itraversed) (\is -> reverse . zipWith (+) is)) im ] , bgroup "singular" [ bench "singular" $ nf (over (singular traversed) id) im , bench "singular/lens" $ nf (L.over (L.singular traverse) id) im ] , bgroup "indices" [ bench "indices" $ nf (iover (itraversed %& indices even) (+)) im , bench "indices/lens" $ nf (L.iover (L.itraversed . L.indices even) (+)) im ] ] , bgroup "map" [ bgroup "traverse" [ bench "native" $ nf (\x -> S.execState (traverse (S.modify' . (+)) x) 0) m , bench "each" $ nf (\x -> S.execState (traverseOf each (S.modify' . (+)) x) 0) m , bench "each/lens" $ nf (\x -> S.execState (L.traverseOf L.each (S.modify' . (+)) x) 0) m , bench "itraversed" $ nf (\x -> S.execState (traverseOf itraversed (S.modify' . (+)) x) 0) m , bench "itraversed/lens" $ nf (\x -> S.execState (L.traverseOf L.itraversed (S.modify' . (+)) x) 0) m ] , bgroup "itraverse" [ bench "native" $ nf (\x -> S.execState (M.traverseWithKey (\i a -> S.modify' $ (i + a +)) x) 0) m , bench "itraverse" $ nf (\x -> S.execState (itraverse (\i a -> S.modify' $ (i + a +)) x) 0) m , bench "itraverse/lens" $ nf (\x -> S.execState (L.itraverse (\i a -> S.modify' $ (i + a +)) x) 0) m , bench "each" $ nf (\x -> S.execState (itraverseOf each (\i a -> S.modify' $ (i + a +)) x) 0) m , bench "itraversed" $ nf (\x -> S.execState (itraverseOf itraversed (\i a -> S.modify' $ (i + a +)) x) 0) m , bench "itraversed/lens" $ nf (\x -> S.execState (L.itraverseOf L.itraversed (\i a -> S.modify' $ (i + a +)) x) 0) m ] , bgroup "map" [ bench "native" $ nf (fmap (+100)) m , bench "each" $ nf (over each (+100)) m , bench "each/lens" $ nf (L.over L.each (+100)) m , bench "itraversed" $ nf (over itraversed (+100)) m , bench "itraversed/lens" $ nf (L.over L.itraversed (+100)) m , bench "imapped" $ nf (over imapped (+100)) m , bench "imapped/lens" $ nf (L.over L.imapped (+100)) m ] , bgroup "imap" [ bench "native" $ nf (M.mapWithKey (\i x -> x + i +100)) m , bench "imap" $ nf (imap (\i x -> x + i +100)) m , bench "imap/lens" $ nf (L.imap (\i x -> x + i +100)) m , bench "each" $ nf (iover each (\i x -> x + i +100)) m , bench "itraversed" $ nf (iover itraversed (\i x -> x + i +100)) m , bench "itraversed/lens" $ nf (L.iover L.itraversed (\i x -> x + i +100)) m , bench "imapped" $ nf (iover imapped (\i x -> x + i +100)) m , bench "imapped/lens" $ nf (L.iover L.imapped (\i x -> x + i +100)) m ] , bgroup "elements" [ bench "itraversed" $ nf (iover itraversed (+)) m , bench "itraversed/lens" $ nf (L.iover L.itraversed (+)) m , bench "elements" $ nf (iover (elements $ const True) (+)) m , bench "elements/lens" $ nf (L.iover (L.elements $ const True) (+)) m ] , bgroup "partsOf" [ bench "partsOf" $ nf (over (partsOf traversed) reverse) m , bench "partsOf/lens" $ nf (L.over (L.partsOf traverse) reverse) m , bench "ipartsOf" $ nf (iover (ipartsOf itraversed) (\is -> reverse . zipWith (+) is)) m , bench "ipartsOf/lens" $ nf (L.iover (L.ipartsOf L.itraversed) (\is -> reverse . zipWith (+) is)) m ] , bgroup "singular" [ bench "singular" $ nf (over (singular traversed) id) m , bench "singular/lens" $ nf (L.over (L.singular traverse) id) m ] , bgroup "indices" [ bench "indices" $ nf (iover (itraversed %& indices even) (+)) m , bench "indices/lens" $ nf (L.iover (L.itraversed . L.indices even) (+)) m ] ] , bgroup "hash map" [ bgroup "traverse" [ bench "native" $ nf (\x -> S.execState (traverse (S.modify' . (+)) x) 0) h , bench "each" $ nf (\x -> S.execState (traverseOf each (S.modify' . (+)) x) 0) h , bench "each/lens" $ nf (\x -> S.execState (L.traverseOf L.each (S.modify' . (+)) x) 0) h , bench "itraversed" $ nf (\x -> S.execState (traverseOf itraversed (S.modify' . (+)) x) 0) h , bench "itraversed/lens" $ nf (\x -> S.execState (L.traverseOf L.itraversed (S.modify' . (+)) x) 0) h ] , bgroup "itraverse" [ bench "native" $ nf (\x -> S.execState (HM.traverseWithKey (\i a -> S.modify' $ (i + a +)) x) 0) h , bench "itraverse" $ nf (\x -> S.execState (itraverse (\i a -> S.modify' $ (i + a +)) x) 0) h , bench "itraverse/lens" $ nf (\x -> S.execState (L.itraverse (\i a -> S.modify' $ (i + a +)) x) 0) h , bench "each" $ nf (\x -> S.execState (itraverseOf each (\i a -> S.modify' $ (i + a +)) x) 0) h , bench "itraversed" $ nf (\x -> S.execState (itraverseOf itraversed (\i a -> S.modify' $ (i + a +)) x) 0) h , bench "itraversed/lens" $ nf (\x -> S.execState (L.itraverseOf L.itraversed (\i a -> S.modify' $ (i + a +)) x) 0) h ] , bgroup "map" [ bench "native" $ nf (HM.map (+100)) h , bench "each" $ nf (over each (+100)) h , bench "each/lens" $ nf (L.over L.each (+100)) h , bench "itraversed" $ nf (over itraversed (+100)) h , bench "itraversed/lens" $ nf (L.over L.itraversed (+100)) h , bench "imapped" $ nf (over imapped (+100)) h , bench "imapped/lens" $ nf (L.over L.imapped (+100)) h ] , bgroup "imap" [ bench "native" $ nf (HM.mapWithKey (\i x -> x + i +100)) h , bench "imap" $ nf (imap (\i x -> x + i +100)) h , bench "imap/lens" $ nf (L.imap (\i x -> x + i +100)) h , bench "each" $ nf (iover each (\i x -> x + i +100)) h , bench "itraversed" $ nf (iover itraversed (\i x -> x + i +100)) h , bench "itraversed/lens" $ nf (L.iover L.itraversed (\i x -> x + i +100)) h , bench "imapped" $ nf (iover imapped (\i x -> x + i +100)) h , bench "imapped/lens" $ nf (L.iover L.imapped (\i x -> x + i +100)) h ] , bgroup "elements" [ bench "itraversed" $ nf (iover itraversed (+)) h , bench "itraversed/lens" $ nf (L.iover L.itraversed (+)) h , bench "elements" $ nf (iover (elements $ const True) (+)) h , bench "elements/lens" $ nf (L.iover (L.elements $ const True) (+)) h ] , bgroup "partsOf" [ bench "partsOf" $ nf (over (partsOf traversed) reverse) h , bench "partsOf/lens" $ nf (L.over (L.partsOf traverse) reverse) h , bench "ipartsOf" $ nf (iover (ipartsOf itraversed) (\is -> reverse . zipWith (+) is)) h , bench "ipartsOf/lens" $ nf (L.iover (L.ipartsOf L.itraversed) (\is -> reverse . zipWith (+) is)) h ] , bgroup "singular" [ bench "singular" $ nf (over (singular traversed) id) h , bench "singular/lens" $ nf (L.over (L.singular traverse) id) h ] , bgroup "indices" [ bench "indices" $ nf (iover (itraversed %& indices even) (+)) h , bench "indices/lens" $ nf (L.iover (L.itraversed . L.indices even) (+)) h ] ] , bgroup "misc" [ bgroup "adjoin" [ bench "hand-written" $ nf (over adjoinHandWritten (+1)) tuple , bench "adjoin" $ nf (over adjoinOptics (+1)) tuple , bench "adjoin/lens" $ nf (L.over adjoinLens (+1)) tuple ] ] ] where l = [0..10000] :: [Int] {-# NOINLINE l #-} xl = [0..100000] :: [Int] {-# NOINLINE xl #-} b = BS.pack $ map fromIntegral xl {-# NOINLINE b #-} bl = BSL.pack $ map fromIntegral [0..1000000::Int] {-# NOINLINE bl #-} h = HM.fromList $ zip l l {-# NOINLINE h #-} m = M.fromList $ zip l l {-# NOINLINE m #-} im = IM.fromList $ zip l l {-# NOINLINE im #-} s = S.fromList l {-# NOINLINE s #-} u = U.fromList xl {-# NOINLINE u #-} v = V.fromList l {-# NOINLINE v #-} tuple :: (Maybe Int, Either Int Int, Int) tuple = (Just 67, Right 567, 23) {-# NOINLINE tuple #-} adjoinHandWritten :: Traversal' (Maybe a, Either a a, a) a adjoinHandWritten = traversalVL $ \f (a, b, c) -> (,,) <$> traverseOf _Just f a <*> traverseOf chosen f b <*> f c adjoinOptics :: Traversal' (Maybe a, Either a a, a) a adjoinOptics = _1 % _Just `adjoin` _2 % chosen `adjoin` _3 adjoinLens :: L.Traversal' (Maybe a, Either a a, a) a adjoinLens = (L._1 . L._Just) `L.adjoin` (L._2 . L.chosen) `L.adjoin` L._3