1import birl
2import gleam/int
3import gleam/io
4import gleam/string
5import internal/llm/day01 as llm_day01
6import internal/mine/day01 as mine_day01
7
8pub type TimedResult {
9 TimedResult(result: Int, microseconds: Int)
10}
11
12fn time_fn(f: fn() -> Int) -> TimedResult {
13 let start = birl.now() |> birl.to_unix_micro
14 let result = f()
15 let end = birl.now() |> birl.to_unix_micro
16 TimedResult(result: result, microseconds: end - start)
17}
18
19fn format_time(microseconds: Int) -> String {
20 case microseconds {
21 us if us < 1000 -> int.to_string(us) <> "µs"
22 us if us < 1_000_000 -> {
23 let ms = us / 1000
24 let remainder = us % 1000
25 int.to_string(ms)
26 <> "."
27 <> string.pad_start(int.to_string(remainder / 100), 1, "0")
28 <> "ms"
29 }
30 us -> {
31 let s = us / 1_000_000
32 let ms = { us % 1_000_000 } / 1000
33 int.to_string(s)
34 <> "."
35 <> string.pad_start(int.to_string(ms), 3, "0")
36 <> "s"
37 }
38 }
39}
40
41fn print_comparison(part: String, mine: TimedResult, llm: TimedResult) -> Nil {
42 io.println("")
43 io.println("--- " <> part <> " ---")
44 io.println(
45 "Mine: "
46 <> int.to_string(mine.result)
47 <> " ("
48 <> format_time(mine.microseconds)
49 <> ")",
50 )
51 io.println(
52 "LLM: "
53 <> int.to_string(llm.result)
54 <> " ("
55 <> format_time(llm.microseconds)
56 <> ")",
57 )
58
59 let match = case mine.result == llm.result {
60 True -> "✓ Results match"
61 False -> "✗ Results differ!"
62 }
63 io.println(match)
64
65 let speedup = case mine.microseconds, llm.microseconds {
66 0, 0 -> "Both too fast to measure"
67 m, _l if m == 0 -> "Mine too fast to measure"
68 _m, l if l == 0 -> "LLM too fast to measure"
69 m, l if m < l -> "Mine " <> format_speedup(l, m) <> " faster"
70 m, l if l < m -> "LLM " <> format_speedup(m, l) <> " faster"
71 _, _ -> "Same speed"
72 }
73 io.println(speedup)
74}
75
76fn format_speedup(slower: Int, faster: Int) -> String {
77 let ratio = { slower * 100 } / faster
78 let whole = ratio / 100
79 let frac = ratio % 100
80 int.to_string(whole)
81 <> "."
82 <> string.pad_start(int.to_string(frac), 2, "0")
83 <> "x"
84}
85
86pub fn day01(input: List(String)) -> Nil {
87 io.println("Comparing implementations...")
88
89 let mine_p1 = time_fn(fn() { mine_day01.part1(input) })
90 let llm_p1 = time_fn(fn() { llm_day01.part1(input) })
91 print_comparison("Part 1", mine_p1, llm_p1)
92
93 let mine_p2 = time_fn(fn() { mine_day01.part2(input) })
94 let llm_p2 = time_fn(fn() { llm_day01.part2(input) })
95 print_comparison("Part 2", mine_p2, llm_p2)
96}