compare.gleam

 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}