Skip to main content

aver/
runtime_bench_cases.rs

1pub struct CoreBenchCase {
2    pub slug: &'static str,
3    pub name: &'static str,
4    pub source: &'static str,
5}
6
7const FIBONACCI: &str = "\
8fn fib(n: Int) -> Int
9    match n < 2
10        true -> n
11        false -> fib(n - 1) + fib(n - 2)
12
13fn main() -> Int
14    fib(25)
15";
16
17const SUM_TCO: &str = "\
18fn sum(n: Int, acc: Int) -> Int
19    match n == 0
20        true -> acc
21        false -> sum(n - 1, acc + n)
22
23fn main() -> Int
24    sum(10000000, 0)
25";
26
27const COUNTDOWN: &str = "\
28fn countdown(n: Int) -> Int
29    match n == 0
30        true -> 0
31        false -> countdown(n - 1)
32
33fn main() -> Int
34    countdown(10000000)
35";
36
37const FACTORIAL_TCO: &str = "\
38fn fact(n: Int, acc: Int) -> Int
39    match n == 0
40        true -> acc
41        false -> fact(n - 1, acc * n)
42
43fn repeat(n: Int, acc: Int) -> Int
44    match n == 0
45        true -> acc
46        false -> repeat(n - 1, acc + Result.withDefault(Int.mod(fact(20, 1), 1000000), 0))
47
48fn main() -> Int
49    repeat(50000, 0)
50";
51
52const NESTED_MATCH: &str = "\
53fn abs(n: Int) -> Int\n    match n < 0\n        true -> 0 - n\n        false -> n\n\nfn classify(n: Int) -> Int\n    match n == 0\n        true -> 0\n        false -> abs(n) * 2\n\nfn run(n: Int, acc: Int) -> Int\n    match n == 0\n        true -> acc\n        false -> run(n - 1, acc + classify(n - 180000))\n\nfn main() -> Int\n    run(360000, 0)\n";
54
55const RESULT_CHAIN: &str = "\
56fn safeDivide(a: Int, b: Int) -> Result<Int, Int>\n    match b == 0\n        true -> Result.Err(0)\n        false -> Result.Ok(a / b)\n\nfn unwrapOr(r: Result<Int, Int>, d: Int) -> Int\n    match r\n        Result.Ok(v) -> v\n        Result.Err(_) -> d\n\nfn chain(n: Int, acc: Int) -> Int\n    match n == 0\n        true -> acc\n        false -> chain(n - 1, acc + unwrapOr(safeDivide(n * 10, n), 0))\n\nfn main() -> Int\n    chain(400000, 0)\n";
57
58const LIST_WALK: &str = "\
59fn build(n: Int, acc: List<Int>) -> List<Int>\n    match n == 0\n        true -> acc\n        false -> build(n - 1, List.prepend(n, acc))\n\nfn listLen(xs: List<Int>, acc: Int) -> Int\n    match xs\n        [] -> acc\n        [h, ..t] -> listLen(t, acc + 1)\n\nfn walkFive(xs: List<Int>) -> Int\n    listLen(xs, 0) + listLen(xs, 0) + listLen(xs, 0) + listLen(xs, 0) + listLen(xs, 0)\n\nfn main() -> Int\n    walkFive(build(100000, []))\n";
60
61const SHAPES: &str = "\
62type Shape\n    Circle(Float)\n    Rect(Float, Float)\n    Point\n\nfn area(s: Shape) -> Float\n    match s\n        Shape.Circle(r) -> r * r * 3.14159\n        Shape.Rect(w, h) -> w * h\n        Shape.Point -> 0.0\n\nfn sumAreas(n: Int, acc: Float) -> Float\n    match n == 0\n        true -> acc\n        false -> sumAreas(n - 1, acc + area(Shape.Circle(1.0)) + area(Shape.Rect(3.0, 4.0)))\n\nfn main() -> Float\n    sumAreas(300000, 0.0)\n";
63
64const RECORD_HEAVY: &str = "\
65record Point\n    x: Int\n    y: Int\n\nfn moveRight(p: Point) -> Point\n    Point.update(p, x = p.x + 1)\n\nfn walk(n: Int, p: Point) -> Int\n    match n == 0\n        true -> p.x + p.y\n        false -> walk(n - 1, moveRight(p))\n\nfn main() -> Int\n    walk(400000, Point(x = 0, y = 0))\n";
66
67const STRING_BUILD: &str = "\
68fn repeat(n: Int, s: String, acc: String) -> String\n    match n == 0\n        true -> acc\n        false -> repeat(n - 1, s, acc + s)\n\nfn main() -> Int\n    r = repeat(20000, \"ab\", \"\")\n    String.len(r)\n";
69
70const ERROR_PIPELINE: &str = "\
71fn validate(n: Int) -> Result<Int, String>\n    match n < 0\n        true -> Result.Err(\"negative\")\n        false -> Result.Ok(n)\n\nfn transform(n: Int) -> Result<Int, String>\n    match n > 1000\n        true -> Result.Err(\"too large\")\n        false -> Result.Ok(n * 2)\n\nfn pipeline(n: Int) -> Result<Int, String>\n    v = validate(n)?\n    transform(v)\n\nfn run(n: Int, acc: Int) -> Int\n    match n == 0\n        true -> acc\n        false -> run(n - 1, acc + Result.withDefault(pipeline(n), 0))\n\nfn main() -> Int\n    run(200000, 0)\n";
72
73const LIST_BUILTINS: &str = "\
74fn buildAndMeasure(n: Int, acc: List<Int>) -> Int\n    match n == 0\n        true -> List.len(acc)\n        false -> buildAndMeasure(n - 1, List.prepend(n, acc))\n\nfn main() -> Int\n    buildAndMeasure(400000, [])\n";
75
76const LIST_APPEND_SCAN: &str = "\
77fn build(n: Int, acc: List<Int>) -> List<Int>\n    match n == 0\n        true -> acc\n        false -> build(n - 1, List.prepend(n, acc))\n\nfn sum(v: Vector<Int>, size: Int, i: Int, acc: Int) -> Int\n    match i == size\n        true -> acc\n        false -> sum(v, size, i + 1, acc + Option.withDefault(Vector.get(v, i), 0))\n\nfn main() -> Int\n    xs = List.reverse(build(12000, []))\n    v = Vector.fromList(xs)\n    sum(v, Vector.len(v), 0, 0)\n";
78
79const MIXED_REAL: &str = "\
80record Order\n    id: Int\n    amount: Int\n    valid: Bool\n\nfn processOrder(o: Order) -> Result<Int, String>\n    match o.valid\n        true -> Result.Ok(o.amount * 2)\n        false -> Result.Err(\"invalid\")\n\nfn processAll(n: Int, acc: Int) -> Int\n    match n == 0\n        true -> acc\n        false -> processAll(n - 1, acc + Result.withDefault(processOrder(Order(id = n, amount = n * 10, valid = true)), 0))\n\nfn main() -> Int\n    processAll(200000, 0)\n";
81
82const LIST_GET_OR: &str = "\
83fn build(n: Int, acc: List<Int>) -> List<Int>\n    match n == 0\n        true -> List.reverse(acc)\n        false -> build(n - 1, List.prepend(n, acc))\n\nfn scan(v: Vector<Int>, size: Int, i: Int, acc: Int) -> Int\n    match i == size\n        true -> acc\n        false -> scan(v, size, i + 1, acc + Option.withDefault(Vector.get(v, i), 0))\n\nfn main() -> Int\n    xs = build(10000, [])\n    v = Vector.fromList(xs)\n    scan(v, 10000, 0, 0) + scan(v, 10000, 0, 0) + scan(v, 10000, 0, 0)\n";
84
85pub const CORE_BENCH_CASES: &[CoreBenchCase] = &[
86    CoreBenchCase {
87        slug: "fib_25",
88        name: "fib(25)",
89        source: FIBONACCI,
90    },
91    CoreBenchCase {
92        slug: "sum_tco_10m",
93        name: "sum_tco(10M)",
94        source: SUM_TCO,
95    },
96    CoreBenchCase {
97        slug: "countdown_10m",
98        name: "countdown(10M)",
99        source: COUNTDOWN,
100    },
101    CoreBenchCase {
102        slug: "factorial_20",
103        name: "factorial(20) x 50K",
104        source: FACTORIAL_TCO,
105    },
106    CoreBenchCase {
107        slug: "nested_match_360k",
108        name: "nested_match(360K)",
109        source: NESTED_MATCH,
110    },
111    CoreBenchCase {
112        slug: "result_chain_400k",
113        name: "result_chain(400K)",
114        source: RESULT_CHAIN,
115    },
116    CoreBenchCase {
117        slug: "list_walk_100k",
118        name: "list_walk(100K x5)",
119        source: LIST_WALK,
120    },
121    CoreBenchCase {
122        slug: "shapes_300k",
123        name: "shapes(300K)",
124        source: SHAPES,
125    },
126    CoreBenchCase {
127        slug: "record_heavy_400k",
128        name: "record_heavy(400K)",
129        source: RECORD_HEAVY,
130    },
131    CoreBenchCase {
132        slug: "string_build_20k",
133        name: "string_build(20K)",
134        source: STRING_BUILD,
135    },
136    CoreBenchCase {
137        slug: "error_pipeline_200k",
138        name: "error_pipeline(200K)",
139        source: ERROR_PIPELINE,
140    },
141    CoreBenchCase {
142        slug: "list_builtins_400k",
143        name: "list_builtins(400K)",
144        source: LIST_BUILTINS,
145    },
146    CoreBenchCase {
147        slug: "list_append_scan_1k",
148        name: "list_append_scan(12K)",
149        source: LIST_APPEND_SCAN,
150    },
151    CoreBenchCase {
152        slug: "mixed_real_200k",
153        name: "mixed_real(200K)",
154        source: MIXED_REAL,
155    },
156    CoreBenchCase {
157        slug: "list_get_or_30k",
158        name: "list_get_or(30K)",
159        source: LIST_GET_OR,
160    },
161];