/** * KvMap Benchmark * * 运行: npx tsx src/only/kvlite/benchmark/kvMap.benchmark.ts */ import { Bench } from "tinybench" import { useKvMap } from "../useKvMap" interface TestData { id: number name: string value: number tags: string[] } async function runBenchmark() { // 初始化内存数据库 const kvMap = await useKvMap(":memory:benchmark") const kvMapFast = await useKvMap(":memory:benchmark-fast", { fastMode: true }) // 预热:初始化一些数据 for (let i = 0; i < 1000; i++) { kvMap.set(`key_${i}`, { id: i, name: `item_${i}`, value: i * 10, tags: ["a", "b"] }) kvMapFast.set(`key${i}`, { id: i, name: `item_${i}`, value: i * 10, tags: ["a", "b"] }) } // 对比用的原生 Map const nativeMap = new Map() for (let i = 0; i < 1000; i++) { nativeMap.set(`warmup_${i}`, { id: i, name: `item_${i}`, value: i * 10, tags: ["a", "b"] }) } let counter = 10000 // ========================================================================= // Benchmark: 基础读写操作 // ========================================================================= const benchBasic = new Bench({ name: "KvMap 基础操作", time: 1000 }) benchBasic .add("KvMap set", () => { kvMap.set(`key_${counter++}`, { id: counter, name: `test_${counter}`, value: counter, tags: ["x"] }) }) .add("Native Map set", () => { nativeMap.set(`key_${counter++}`, { id: counter, name: `test_${counter}`, value: counter, tags: ["x"] }) }) .add("KvMap get (existing)", () => { kvMap.get("warmup_500") }) .add("Native Map get (existing)", () => { nativeMap.get("warmup_500") }) .add("KvMap get (non-existing)", () => { kvMap.get("non_existing_key") }) .add("Native Map get (non-existing)", () => { nativeMap.get("non_existing_key") }) await benchBasic.run() console.log("\n" + benchBasic.name) console.table(benchBasic.table()) // ========================================================================= // Benchmark: 批量操作 // ========================================================================= const benchBatch = new Bench({ name: "KvMap 批量操作", time: 500 }) benchBatch .add("KvMap getAll (1000 items)", () => { kvMap.getAll() }) .add("KvMap keys (1000 items)", () => { kvMap.keys() }) .add("KvMap count", () => { kvMap.count() }) .add("KvMap forEach", () => { let sum = 0 kvMap.forEach(([key, data]) => { sum += data.value }) }) await benchBatch.run() console.log("\n" + benchBatch.name) console.table(benchBatch.table()) // ========================================================================= // Benchmark: 删除操作 // ========================================================================= // 先准备删除用的数据 for (let i = 0; i < 5000; i++) { kvMap.set(`delete_${i}`, { id: i, name: `del_${i}`, value: i, tags: [] }) } let deleteCounter = 0 const benchDelete = new Bench({ name: "KvMap 删除操作", time: 500 }) benchDelete.add("KvMap delete", () => { kvMap.delete(`delete_${deleteCounter++}`) }) await benchDelete.run() console.log("\n" + benchDelete.name) console.table(benchDelete.table()) // ========================================================================= // Benchmark: 更新操作 // ========================================================================= const benchUpdate = new Bench({ name: "KvMap 更新操作", time: 500 }) let updateCounter = 0 benchUpdate .add("KvMap update (set field)", () => { kvMap.update(`warmup_${updateCounter % 1000}`, { $set: { value: updateCounter++ } }) }) .add("KvMap set (overwrite)", () => { kvMap.set(`warmup_${updateCounter % 1000}`, { id: updateCounter, name: `updated_${updateCounter}`, value: updateCounter++, tags: ["updated"], }) }) await benchUpdate.run() console.log("\n" + benchUpdate.name) console.table(benchUpdate.table()) // ========================================================================= // Benchmark: 查询操作 // ========================================================================= const benchQuery = new Bench({ name: "KvMap 查询操作", time: 500 }) benchQuery .add("KvMap find (by key pattern)", () => { kvMap.find({ key: { $like: "warmup_1%" } }) }) .add("KvMap find (with limit)", () => { kvMap.find({}, { limit: 10 }) }) .add("KvMap some (early exit)", () => { kvMap.some((data, key, index) => { return index >= 10 }) }) await benchQuery.run() console.log("\n" + benchQuery.name) console.table(benchQuery.table()) // ========================================================================= // 汇总 // ========================================================================= console.log("\n========================================") console.log("Benchmark 完成!") console.log("========================================") } runBenchmark().catch(console.error)