Created
June 7, 2026 13:08
-
-
Save fendor/51a41bd4eed8d41fda79f2c36e0e86a7 to your computer and use it in GitHub Desktop.
MicroBenchmark for HLS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env cabal | |
| {- cabal: | |
| build-depends: | |
| base >= 4.7 && < 5, | |
| criterion >= 1.6 && < 2, | |
| containers >= 0.6 && < 1, | |
| vector >= 0.12 && < 1 | |
| -} | |
| -- Run with: cabal run bench.hs | |
| -- (no project setup needed — cabal script handles everything) | |
| module Main (main) where | |
| import Criterion.Main | |
| import qualified Data.Set as Set | |
| import qualified Data.Vector as Vector | |
| -- | Configurable base extensions and boot suffix. | |
| baseExts :: [String] | |
| baseExts = [".hs", ".lhs"] | |
| bootSuffix :: String | |
| bootSuffix = "-boot" | |
| -- | The canonical 4-element collection, derived from the config above. | |
| extensions :: [String] | |
| extensions = baseExts ++ map (++ bootSuffix) baseExts | |
| -- => [".hs", ".lhs", ".hs-boot", ".lhs-boot"] | |
| -- -------------------------------------------------------------------------- | |
| -- Representations built once and shared across benchmark runs. | |
| -- -------------------------------------------------------------------------- | |
| extList :: [String] | |
| extList = extensions | |
| extSet :: Set.Set String | |
| extSet = Set.fromList extensions | |
| extVec :: Vector.Vector String | |
| extVec = Vector.fromList extensions | |
| -- -------------------------------------------------------------------------- | |
| -- Membership predicates | |
| -- -------------------------------------------------------------------------- | |
| memberList :: String -> Bool | |
| memberList x = x `elem` extList | |
| memberSet :: String -> Bool | |
| memberSet x = x `Set.member` extSet | |
| memberVec :: String -> Bool | |
| memberVec x = x `Vector.elem` extVec | |
| -- -------------------------------------------------------------------------- | |
| -- Probe values: mix of hits and misses so neither branch is dead code. | |
| -- -------------------------------------------------------------------------- | |
| probes :: [String] | |
| probes = | |
| [ ".hs" -- hit (first) | |
| , ".lhs" -- hit (second) | |
| , ".hs-boot" -- hit (third) | |
| , ".lhs-boot" -- hit (fourth / last) | |
| , ".c" -- miss | |
| , ".js" -- miss | |
| , ".py" -- miss | |
| ] | |
| -- | Force all membership checks so the optimiser cannot drop them. | |
| checkAll :: (String -> Bool) -> Bool | |
| checkAll f = all f (take 4 probes) && not (any f (drop 4 probes)) | |
| -- ^^^^^^^^^^^^ 4 hits ^^^^^^^^^^^^^^^ 3 misses | |
| -- -------------------------------------------------------------------------- | |
| -- Main | |
| -- -------------------------------------------------------------------------- | |
| main :: IO () | |
| main = defaultMain | |
| [ bgroup "membership / 4-element collection" | |
| [ bgroup "list" | |
| [ bench "hit first (.hs)" $ whnf memberList ".hs" | |
| , bench "hit last (.lhs-boot)"$ whnf memberList ".lhs-boot" | |
| , bench "miss (.py)" $ whnf memberList ".py" | |
| , bench "all probes" $ whnf checkAll memberList | |
| ] | |
| , bgroup "Set" | |
| [ bench "hit first (.hs)" $ whnf memberSet ".hs" | |
| , bench "hit last (.lhs-boot)"$ whnf memberSet ".lhs-boot" | |
| , bench "miss (.py)" $ whnf memberSet ".py" | |
| , bench "all probes" $ whnf checkAll memberSet | |
| ] | |
| , bgroup "Vector" | |
| [ bench "hit first (.hs)" $ whnf memberVec ".hs" | |
| , bench "hit last (.lhs-boot)"$ whnf memberVec ".lhs-boot" | |
| , bench "miss (.py)" $ whnf memberVec ".py" | |
| , bench "all probes" $ whnf checkAll memberVec | |
| ] | |
| ] | |
| ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment