lean4-htt/tests/compile_bench/iterators.lean
Garmelon 08eb78a5b2
chore: switch to new test/bench suite (#12590)
This PR sets up the new integrated test/bench suite. It then migrates
all benchmarks and some related tests to the new suite. There's also
some documentation and some linting.

For now, a lot of the old tests are left alone so this PR doesn't become
even larger than it already is. Eventually, all tests should be migrated
to the new suite though so there isn't a confusing mix of two systems.
2026-02-25 13:51:53 +00:00

112 lines
3.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Std.Data.Iterators
/-
This benchmark measures the performance of iterators. The file starts with various function
declarations. The functions are then called from `main`.
The benchmark is run in three settings.
* The runtime of the compiled program is measured in `iterators (compiled)`.
* The time taken to interpret the script, including running `main`, is measured in
`iterators (interpreted)`.
* The time taken to interpret the script, without running `main`, is measured in
`interators (elab)`.
-/
/- definitions -/
def sum₁ (xs : Array Nat) : Nat :=
xs.iter.fold (init := 0) (· + ·)
def sum₂ (xs : Array Nat) : Nat := Id.run do
let mut sum := 0
for x in xs do
sum := sum + x
return sum
def isolatedMap (xs : Array Nat) : Nat :=
xs.iter.map (· * 2) |>.fold (init := 0) (· + ·)
def isolatedFilterMap (xs : Array Nat) : Nat :=
xs.iter.filterMap (fun x => Option.guard (· % 2 = 0) (3 * x)) |>.fold (init := 0) (· + ·)
def isolatedTake (xs : Array Nat) (n : Nat) : Nat :=
xs.iter.take n |>.fold (init := 0) (· + ·)
def isolatedDrop (xs : Array Nat) (n : Nat) : Nat :=
xs.iter.drop n |>.fold (init := 0) (· + ·)
def isolatedTakeWhile (xs : Array Nat) : Nat :=
xs.iter.takeWhile (· < 100000) |>.fold (init := 0) (· + ·)
def isolatedDropWhile (xs : Array Nat) : Nat :=
xs.iter.dropWhile (· < 100000) |>.fold (init := 0) (· + ·)
def isolatedZip (xs : Array Nat) (ys : Array Nat) : Nat :=
xs.iter.zip ys.iter |>.fold (init := 0) (fun | acc, (a, b) => acc + a * b)
def isolatedSteppedRange (n : Nat) : Nat :=
(*...n).iter.stepSize 2 |>.fold (init := 0) (· + ·)
section Primes
def numDivisors (n : Nat) := (1...=n).iter
|>.filter (n % · = 0)
|>.count
def isPrime (n : Nat) := numDivisors n == 2
def primes (n : Nat) := (*...* : Std.Rii Nat).iter.take n
|>.filter isPrime
|>.toList
end Primes
def printEveryNth (xs : List Nat) (n : Nat) : IO Unit := do
for x in xs, i in (*...* : Std.Rii Nat) do
if i % n = 0 then
IO.println s!"xs[{i}] = {x}"
def printEveryNthSliceBased (xs : Array Nat) (n : Nat) : IO Unit := do
for x in xs[*...*], i in (*...* : Std.Rii Nat) do
if i % n = 0 then
IO.println s!"xs[{i}] = {x}"
def longChainOfCombinators (xs : Array Nat) : Nat :=
xs.iter.zip (2...*).iter
|>.filter (fun | (_, i) => i % 2 = 0)
|>.attachWith (fun _ => True) (fun _ _ => .intro)
|>.map (fun x => x.1.2)
|>.drop 1
|>.take 10000000
|>.takeWhile (fun x => x < 5000000)
|>.fold (init := 0) (· + ·)
def xs : Array Nat := (*...100000).iter.toArray
def l : List Nat := (*...100000).iter.toList
/- evaluations -/
@[noinline]
def run' (f : Unit → α) : IO α := do
return f ()
notation "run " t => (fun _ => ()) <$> run' fun _ => t
def main : IO Unit := do
run sum₁ xs
run sum₂ xs
run isolatedMap xs
run isolatedFilterMap xs
run isolatedTake xs 1000000
run isolatedDrop xs 1000000
run isolatedTakeWhile xs
run isolatedDropWhile xs
run isolatedZip xs xs
run isolatedSteppedRange 1000000
run longChainOfCombinators xs
run (*...1000000).iter.fold (init := 0) (· + ·)
run primes 3000
printEveryNth l 10000
printEveryNthSliceBased xs 10000