session-timeline.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { Keyed } from "@opencode-ai/quark"
  2. import { createStore, produce } from "solid-js/store"
  3. import { SessionTimeline, type PartRef } from "../src/routes/session/timeline"
  4. import { createHarness, type Workload } from "../../quark/bench/harness"
  5. type Group = {
  6. readonly id: "group"
  7. readonly type: "group"
  8. readonly refs: readonly PartRef[]
  9. }
  10. const bench = createHarness({ warmup: 500 })
  11. function timelineAppend(): Workload {
  12. const timeline = SessionTimeline.make()
  13. let ordinal = 0
  14. return {
  15. run() {
  16. timeline.appendPart({ messageID: "assistant", partID: `reasoning:${ordinal++}` }, { type: "reasoning" })
  17. },
  18. consume: () => {
  19. const row = timeline.values()[0]
  20. return row?.type === "group" ? row.refs.length : 0
  21. },
  22. }
  23. }
  24. function keyedAppend(): Workload {
  25. const seen = new Set<string>()
  26. const rows = Keyed.make<Group, Group["id"]>({
  27. key: (row) => row.id,
  28. equivalent: (left, right) =>
  29. left.refs.length === right.refs.length &&
  30. left.refs.every(
  31. (ref, index) => ref.messageID === right.refs[index].messageID && ref.partID === right.refs[index].partID,
  32. ),
  33. })
  34. rows.set([{ id: "group", type: "group", refs: [] }])
  35. let ordinal = 0
  36. return {
  37. run() {
  38. const ref = { messageID: "assistant", partID: `reasoning:${ordinal++}` }
  39. if (seen.has(ref.partID)) return
  40. rows.modify("group", (group) => ({ ...group, refs: [...group.refs, ref] }))
  41. seen.add(ref.partID)
  42. },
  43. consume: () => rows.get("group")!().refs.length,
  44. }
  45. }
  46. function solidAppend(): Workload {
  47. const [rows, setRows] = createStore<Array<{ type: "group"; refs: PartRef[] }>>([{ type: "group", refs: [] }])
  48. let ordinal = 0
  49. return {
  50. run() {
  51. const ref = { messageID: "assistant", partID: `reasoning:${ordinal++}` }
  52. setRows(
  53. produce((draft) => {
  54. if (draft[0].refs.some((item) => item.messageID === ref.messageID && item.partID === ref.partID)) return
  55. draft[0].refs.push(ref)
  56. }),
  57. )
  58. },
  59. consume: () => rows[0].refs.length,
  60. }
  61. }
  62. function timelineDuplicate(size: number): Workload {
  63. const timeline = SessionTimeline.make()
  64. Array.from({ length: size }, (_, ordinal) =>
  65. timeline.appendPart({ messageID: "assistant", partID: `reasoning:${ordinal}` }, { type: "reasoning" }),
  66. )
  67. const duplicate = { messageID: "assistant", partID: `reasoning:${size - 1}` }
  68. return {
  69. run: () => timeline.appendPart(duplicate, { type: "reasoning" }),
  70. consume: () => timeline.values().length,
  71. }
  72. }
  73. function solidDuplicate(size: number): Workload {
  74. const refs = Array.from(
  75. { length: size },
  76. (_, ordinal): PartRef => ({ messageID: "assistant", partID: `reasoning:${ordinal}` }),
  77. )
  78. const [rows, setRows] = createStore([{ type: "group" as const, refs }])
  79. const duplicate = refs.at(-1)!
  80. return {
  81. run() {
  82. setRows(
  83. produce((draft) => {
  84. if (draft[0].refs.some((item) => item.messageID === duplicate.messageID && item.partID === duplicate.partID))
  85. return
  86. draft[0].refs.push(duplicate)
  87. }),
  88. )
  89. },
  90. consume: () => rows.length,
  91. }
  92. }
  93. console.log(`Session timeline benchmark (${bench.samples} samples)\n`)
  94. const append = bench.compare(2_000, [
  95. { name: "SessionTimeline grouped append", make: timelineAppend },
  96. { name: "Handwritten Keyed + Set append", make: keyedAppend },
  97. { name: "Solid Store produce append", make: solidAppend },
  98. ])
  99. const duplicate = bench.compare(10_000, [
  100. { name: "SessionTimeline duplicate 1000", make: () => timelineDuplicate(1_000) },
  101. { name: "Solid Store duplicate 1000", make: () => solidDuplicate(1_000) },
  102. ])
  103. console.log("\nRatios (lower is faster)")
  104. console.log(`Timeline / handwritten append: ${append.ratio(0, 1).toFixed(3)}x`)
  105. console.log(`Timeline / Solid append: ${append.ratio(0, 2).toFixed(3)}x`)
  106. console.log(`Timeline / Solid duplicate: ${duplicate.ratio(0, 1).toFixed(3)}x`)
  107. console.log(`METRIC timeline_handwritten_append_ratio=${append.ratio(0, 1).toFixed(6)}`)
  108. console.log(`METRIC timeline_solid_append_ratio=${append.ratio(0, 2).toFixed(6)}`)
  109. console.log(`METRIC timeline_solid_duplicate_ratio=${duplicate.ratio(0, 1).toFixed(6)}`)
  110. bench.finish()