bench-search.ts 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { Effect } from "effect"
  2. import { Fff } from "@kirincode-ai/core/filesystem/fff.bun"
  3. import { AppRuntime } from "@/effect/app-runtime"
  4. import { FileSystem } from "@kirincode-ai/core/filesystem"
  5. import { AbsolutePath } from "@kirincode-ai/core/schema"
  6. import { InstanceStore } from "@/project/instance-store"
  7. const dir = AbsolutePath.make(process.cwd())
  8. const FILE_QUERIES = ["fff", "package.json", "tools/ experiment"]
  9. const GREP_QUERIES = ["FileFinder", "import", "grep", "autocomplete"]
  10. const GLOB_QUERIES = ["**/*.test.ts"]
  11. const FILE_LIMIT = 100
  12. const GREP_LIMIT = 50
  13. const GLOB_LIMIT = 50
  14. const run = <A, R>(effect: Effect.Effect<A, unknown, R>) =>
  15. AppRuntime.runPromise(
  16. InstanceStore.Service.use((store) => store.provide({ directory: dir }, effect as never)),
  17. ) as Promise<A>
  18. // --- raw Fff picker ---
  19. const t0 = performance.now()
  20. const made = Fff.create({ basePath: dir, aiMode: true })
  21. if (!made.ok) {
  22. console.error("Fff.create failed:", made.error)
  23. process.exit(1)
  24. }
  25. const picker = made.value
  26. console.log(`picker create: ${(performance.now() - t0).toFixed(1)}ms`)
  27. const tw = performance.now()
  28. await picker.waitForScan(2_500)
  29. console.log(`wait for scan: ${(performance.now() - tw).toFixed(1)}ms`)
  30. // warmup grep to let the content index build
  31. const tWarmup = performance.now()
  32. picker.grep("_warmup_", { mode: "regex", maxMatchesPerFile: 1, timeBudgetMs: 1_500 })
  33. console.log(`grep warmup: ${(performance.now() - tWarmup).toFixed(1)}ms`)
  34. console.log()
  35. console.log("--- raw picker (warm) ---")
  36. for (const q of FILE_QUERIES) {
  37. const t = performance.now()
  38. const r = picker.fileSearch(q, { pageSize: Math.max(FILE_LIMIT, 100) })
  39. const count = r.ok ? r.value.items.length : "err"
  40. console.log(`[picker] fileSearch "${q}": ${(performance.now() - t).toFixed(1)}ms (${count} results)`)
  41. }
  42. for (const q of GREP_QUERIES) {
  43. const t = performance.now()
  44. const r = picker.grep(q, { mode: "regex", pageSize: GREP_LIMIT, timeBudgetMs: 1_500 })
  45. const count = r.ok ? r.value.items.length : "err"
  46. console.log(`[picker] grep "${q}": ${(performance.now() - t).toFixed(1)}ms (${count} matches)`)
  47. }
  48. picker.destroy()
  49. // --- Search service: init breakdown ---
  50. console.log()
  51. // 1) runtime + InstanceState + picker create + scan poll
  52. const tRuntime = performance.now()
  53. console.log(`[Search] init file (runtime + picker + scan): ${(performance.now() - tRuntime).toFixed(1)}ms`)
  54. // 2) grep warmup (content index cold-start inside the Search service picker)
  55. const tGrepWarmup = performance.now()
  56. await run(FileSystem.Service.use((svc) => svc.grep({ pattern: "_warmup_grep_", limit: 1 })))
  57. console.log(`[Search] init grep (content index warmup): ${(performance.now() - tGrepWarmup).toFixed(1)}ms`)
  58. console.log()
  59. console.log("--- Search service (warm) ---")
  60. for (const q of FILE_QUERIES) {
  61. const t = performance.now()
  62. const r = await run(FileSystem.Service.use((svc) => svc.find({ query: q, limit: FILE_LIMIT })))
  63. console.log(`[Search.find] "${q}": ${(performance.now() - t).toFixed(1)}ms (${r.length} results)`)
  64. }
  65. for (const q of GREP_QUERIES) {
  66. const t = performance.now()
  67. const r = await run(FileSystem.Service.use((svc) => svc.grep({ pattern: q, limit: GREP_LIMIT })))
  68. console.log(`[Search.grep] "${q}": ${(performance.now() - t).toFixed(1)}ms (${r.length} matches)`)
  69. }
  70. for (const q of GLOB_QUERIES) {
  71. const t = performance.now()
  72. const r = await run(FileSystem.Service.use((svc) => svc.glob({ pattern: q, limit: GLOB_LIMIT })))
  73. console.log(`[Search.glob] "${q}": ${(performance.now() - t).toFixed(1)}ms (${r.length} files)`)
  74. }
  75. process.exit(0)