diff --git a/benches/arrays.rs b/benches/arrays.rs index 74c30ed3..06e36577 100644 --- a/benches/arrays.rs +++ b/benches/arrays.rs @@ -109,6 +109,15 @@ config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flam name = "sort normal", path = "arrays/sort", args = (20), + }, { + name = "sum normal 50", + path = "arrays/sum", + args = (50), + }, { + name = "sum deepseq 50", + path = "arrays/sum", + args = (50), + eval_mode = EvalMode::DeepSeq, } } criterion_main!(benches); diff --git a/benches/arrays/primes.ncl b/benches/arrays/primes.ncl new file mode 100644 index 00000000..dd932b77 --- /dev/null +++ b/benches/arrays/primes.ncl @@ -0,0 +1,37 @@ +let range + | doc "Generate an array of integers in the range [`start`, `end`)." + | Num -> Num -> Array Num + = fun start end => + if end <= start then + [] + else + array.generate (fun x => x + start) (end - start) +in + +let is_prime + | doc "Returns true if the argument is a prime number." + = fun x => x > 1 && array.all (fun d => x % d != 0) (range 2 (x - 1)) +in + +let Prime = contract.from_predicate is_prime in + +let primes + | doc "Generate `max` primes using Sieve of Eratosthenes." + | Num -> Array Prime + = fun max => + let limit = num.pow max (1 / 2) in # sqrt(max) + let drop_multiples = fun x xs => + let to_drop = max + |> array.generate (fun y => (y + 2) * x) + |> array.filter (fun y => y <= max) in + array.filter (fun y => array.all ((!=) y) to_drop) xs in + let rec loop = fun x xs => + if x > limit then + xs + else + loop (x + 1) (drop_multiples x xs) in + loop 2 (range 2 max) in + +{ + run = primes +} diff --git a/benches/arrays/sum.ncl b/benches/arrays/sum.ncl new file mode 100644 index 00000000..d5cc1ff2 --- /dev/null +++ b/benches/arrays/sum.ncl @@ -0,0 +1,8 @@ +let sum + | Array Num -> Num + = fun xs => + if array.length xs == 0 then 0 + else array.head xs + sum (array.tail xs) +in { + run = fun n => array.generate (fun x => x + 1) n |> sum +}