Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / benchmark / list / test / list_test.gleam
3.3 kB 117 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2025 The Gleam contributors 3 4import benchmarks.{print_results} 5import gleam/list 6import gleamy/bench 7 8pub fn main() { 9 print_results([bench_odd_nums_between(), bench_count_ones(), bench_slice()]) 10} 11 12fn bench_odd_nums_between() -> bench.BenchResults { 13 let odd_nums_between = fn(args) { 14 let #(start, end) = args 15 odd_nums_between(start, end, []) 16 } 17 18 bench.run( 19 [ 20 bench.Input("[0, 100)", #(0, 100)), 21 bench.Input("[0, 1000)", #(0, 1000)), 22 bench.Input("[0, 10_000)", #(0, 10_000)), 23 bench.Input("[0, 100_000)", #(0, 100_000)), 24 bench.Input("[0, 1_000_000)", #(0, 1_000_000)), 25 ], 26 [bench.Function("odd_nums_between", odd_nums_between)], 27 [bench.Duration(1000), bench.Warmup(100)], 28 ) 29} 30 31/// Returns a list of numbers from `start` up to, but not including, `end`. 32fn odd_nums_between(start: Int, end: Int, acc: List(Int)) -> List(Int) { 33 case start { 34 start if start >= end -> list.reverse(acc) 35 _ -> { 36 let acc = case start { 37 n if n % 2 == 1 -> [n, ..acc] 38 _ -> acc 39 } 40 odd_nums_between(start + 1, end, acc) 41 } 42 } 43} 44 45fn bench_count_ones() -> bench.BenchResults { 46 let create_list = fn(size) { 47 list.range(0, size) 48 |> list.map(fn(n) { 49 case n { 50 _ if n % 3 == 0 -> 1 51 _ -> 0 52 } 53 }) 54 } 55 56 let count_ones = fn(list) { count_ones(list, 0) } 57 58 bench.run( 59 [ 60 bench.Input("100 numbers", create_list(100)), 61 bench.Input("1000 numbers", create_list(1000)), 62 bench.Input("10_000 numbers", create_list(10_000)), 63 bench.Input("100_000 numbers", create_list(100_000)), 64 bench.Input("1_000_000 numbers", create_list(1_000_000)), 65 ], 66 [bench.Function("count_ones", count_ones)], 67 [bench.Duration(1000), bench.Warmup(100)], 68 ) 69} 70 71/// Counts the number of ones in a list. 72fn count_ones(list: List(Int), count: Int) -> Int { 73 case list { 74 [] -> count 75 [1, ..tail] -> count_ones(tail, count + 1) 76 [_, ..tail] -> count_ones(tail, count) 77 } 78} 79 80fn bench_slice() -> bench.BenchResults { 81 let list = list.range(0, 1_000_000) 82 83 let slice = fn(args) { 84 let #(list, start, end) = args 85 slice(list, start, end, []) 86 } 87 88 bench.run( 89 [ 90 bench.Input("[0, 1000)", #(list, 0, 1000)), 91 bench.Input("[0, 10_000)", #(list, 0, 10_000)), 92 bench.Input("[0, 100_000)", #(list, 0, 100_000)), 93 bench.Input("[999_000, 1_000_000)", #(list, 999_000, 1_000_000)), 94 bench.Input("[990_000, 1_000_000)", #(list, 990_000, 1_000_000)), 95 bench.Input("[900_000, 1_000_000)", #(list, 900_000, 1_000_000)), 96 bench.Input("[0, 1_000_000)", #(list, 0, 1_000_000)), 97 ], 98 [bench.Function("slice", slice)], 99 [bench.Duration(1000), bench.Warmup(100)], 100 ) 101} 102 103/// Slices a list. 104fn slice(list: List(Int), start: Int, end: Int, acc: List(Int)) -> List(Int) { 105 case list { 106 // If the first element is before the slice, skip it. 107 [_, ..tail] if start > 0 -> { 108 slice(tail, start - 1, end - 1, acc) 109 } 110 // If the first element is within the slice, add it to the accumulator. 111 [head, ..tail] if end > 0 -> { 112 slice(tail, start - 1, end - 1, [head, ..acc]) 113 } 114 // Otherwise, return the accumulator. 115 _ -> list.reverse(acc) 116 } 117}