@yuants/app-virtual-exchange 0.18.6 → 0.18.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-virtual-exchange.d.ts +1 -0
- package/dist/credential.js.map +1 -1
- package/dist/general.js +17 -0
- package/dist/general.js.map +1 -1
- package/dist/legacy-services.js.map +1 -1
- package/dist/position.js.map +1 -1
- package/dist/quote/__tests__/implementations.test.js +1 -1
- package/dist/quote/__tests__/implementations.test.js.map +1 -1
- package/dist/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
- package/dist/quote/benchmark/PerformanceTester.js.map +1 -1
- package/dist/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
- package/dist/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
- package/dist/quote/benchmark/index.js.map +1 -1
- package/dist/quote/benchmark/test-helpers.js.map +1 -1
- package/dist/quote/benchmark/worker.js.map +1 -1
- package/dist/quote/implementations/v0.js.map +1 -1
- package/dist/quote/implementations/v1.js.map +1 -1
- package/dist/quote/implementations/v2.js.map +1 -1
- package/dist/quote/implementations/v3.js +1 -1
- package/dist/quote/implementations/v3.js.map +1 -1
- package/dist/quote/scheduler.js.map +1 -1
- package/dist/quote/service.js.map +1 -1
- package/dist/quote/state.benchmark.js.map +1 -1
- package/dist/series-collector/backwards-interest-rate.js.map +1 -1
- package/dist/series-collector/backwards-ohlc.js.map +1 -1
- package/dist/series-collector/discovery.js.map +1 -1
- package/dist/series-collector/forwards-interest-rate.js.map +1 -1
- package/dist/series-collector/forwards-ohlc.js.map +1 -1
- package/dist/series-collector/patch-interest-rate.js.map +1 -1
- package/dist/series-collector/patch-ohlc.js.map +1 -1
- package/dist/series-collector/setup.js.map +1 -1
- package/dist/series-data/fifo-queue.js.map +1 -1
- package/dist/series-data/scheduler.js.map +1 -1
- package/lib/credential.d.ts +1 -2
- package/lib/credential.d.ts.map +1 -1
- package/lib/credential.js.map +1 -1
- package/lib/general.js +17 -0
- package/lib/general.js.map +1 -1
- package/lib/legacy-services.js.map +1 -1
- package/lib/position.d.ts.map +1 -1
- package/lib/position.js.map +1 -1
- package/lib/quote/__tests__/implementations.test.js +1 -1
- package/lib/quote/__tests__/implementations.test.js.map +1 -1
- package/lib/quote/benchmark/ForkedQuoteStateComparisonTest.js.map +1 -1
- package/lib/quote/benchmark/PerformanceTester.d.ts +0 -1
- package/lib/quote/benchmark/PerformanceTester.d.ts.map +1 -1
- package/lib/quote/benchmark/PerformanceTester.js.map +1 -1
- package/lib/quote/benchmark/QuoteStateComparisonTest.js.map +1 -1
- package/lib/quote/benchmark/QuoteStateTestRunner.js.map +1 -1
- package/lib/quote/benchmark/index.js +2 -2
- package/lib/quote/benchmark/index.js.map +1 -1
- package/lib/quote/benchmark/test-helpers.js +4 -5
- package/lib/quote/benchmark/test-helpers.js.map +1 -1
- package/lib/quote/benchmark/worker.js.map +1 -1
- package/lib/quote/implementations/v0.js +1 -2
- package/lib/quote/implementations/v0.js.map +1 -1
- package/lib/quote/implementations/v1.js.map +1 -1
- package/lib/quote/implementations/v2.js.map +1 -1
- package/lib/quote/implementations/v3.js +1 -1
- package/lib/quote/implementations/v3.js.map +1 -1
- package/lib/quote/scheduler.d.ts.map +1 -1
- package/lib/quote/scheduler.js.map +1 -1
- package/lib/quote/service.js.map +1 -1
- package/lib/quote/state.benchmark.js.map +1 -1
- package/lib/quote/types.d.ts +2 -2
- package/lib/quote/types.d.ts.map +1 -1
- package/lib/series-collector/backwards-interest-rate.d.ts +1 -2
- package/lib/series-collector/backwards-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/backwards-interest-rate.js.map +1 -1
- package/lib/series-collector/backwards-ohlc.d.ts +1 -2
- package/lib/series-collector/backwards-ohlc.d.ts.map +1 -1
- package/lib/series-collector/backwards-ohlc.js.map +1 -1
- package/lib/series-collector/discovery.js.map +1 -1
- package/lib/series-collector/forwards-interest-rate.d.ts +1 -2
- package/lib/series-collector/forwards-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/forwards-interest-rate.js.map +1 -1
- package/lib/series-collector/forwards-ohlc.d.ts +1 -2
- package/lib/series-collector/forwards-ohlc.d.ts.map +1 -1
- package/lib/series-collector/forwards-ohlc.js.map +1 -1
- package/lib/series-collector/patch-interest-rate.d.ts +1 -2
- package/lib/series-collector/patch-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/patch-interest-rate.js.map +1 -1
- package/lib/series-collector/patch-ohlc.d.ts +1 -2
- package/lib/series-collector/patch-ohlc.d.ts.map +1 -1
- package/lib/series-collector/patch-ohlc.js.map +1 -1
- package/lib/series-collector/setup.js.map +1 -1
- package/lib/series-collector/sql-helpers.d.ts.map +1 -1
- package/lib/series-data/fifo-queue.d.ts.map +1 -1
- package/lib/series-data/fifo-queue.js.map +1 -1
- package/lib/series-data/scheduler.js.map +1 -1
- package/lib/tsdoc-metadata.json +11 -0
- package/package.json +42 -42
- package/temp/app-virtual-exchange.api.json +193 -0
- package/temp/app-virtual-exchange.api.md +9 -0
- package/temp/build/typescript/ts_KjrfbUqK.json +1 -0
- package/temp/test/jest/haste-map-76b16e3ab892e2fd05068740b7223d57-a6c52f003baf5bf33cffc52364f3bd7a-4ce9ff2cd20d69bbaecd1543c7e32e02 +0 -0
- package/temp/test/jest/perf-cache-76b16e3ab892e2fd05068740b7223d57-da39a3ee5e6b4b0d3255bfef95601890 +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/QuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteState } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { QuoteStateTestRunner } from './QuoteStateTestRunner';\n\n/**\n * 行情状态对比测试类\n * 用于比较两个不同的 IQuoteState 实现\n */\nexport class QuoteStateComparisonTest {\n private runnerA: QuoteStateTestRunner;\n private runnerB: QuoteStateTestRunner;\n private nameA: string;\n private nameB: string;\n\n constructor(\n createStateA: () => IQuoteState,\n createStateB: () => IQuoteState,\n nameA: string = '实现A',\n nameB: string = '实现B',\n ) {\n this.runnerA = new QuoteStateTestRunner(createStateA);\n this.runnerB = new QuoteStateTestRunner(createStateB);\n this.nameA = nameA;\n this.nameB = nameB;\n }\n\n /**\n * 打印对比结果\n */\n private printComparisonResults(\n resultsA: any[],\n resultsB: any[],\n testType: string,\n key: string = 'time',\n ): void {\n console.log('\\n' + '='.repeat(100));\n console.log(`行情状态性能对比测试 - ${testType}`);\n console.log('='.repeat(100));\n\n console.log(`\\n${this.nameA} vs ${this.nameB} 性能对比:`);\n console.log('-'.repeat(80));\n\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const resultA = resultsA[i];\n const resultB = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = resultA.success === false;\n const isBFailed = resultB.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${resultA.productCount || resultB.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${resultA.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${PerformanceTester.formatTime(resultA.avgTime || resultA.time)}`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${resultB.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${PerformanceTester.formatTime(resultB.avgTime || resultB.time)}`);\n }\n\n console.log('-'.repeat(80));\n continue;\n }\n\n if (resultA.productCount !== resultB.productCount) {\n console.log(`\\n⚠️ 产品数量不匹配: ${resultA.productCount} vs ${resultB.productCount}`);\n continue;\n }\n\n console.log(`\\n产品数量: ${resultA.productCount.toLocaleString()}`);\n\n // 自动检测使用哪个时间字段\n const timeKey = resultA.avgTime !== undefined ? 'avgTime' : 'time';\n const valueA = resultA[timeKey];\n const valueB = resultB[timeKey];\n\n const timeLabel = timeKey === 'avgTime' ? '平均时间' : '时间';\n console.log(`${this.nameA} (${timeLabel}): ${PerformanceTester.formatTime(valueA)}`);\n console.log(`${this.nameB} (${timeLabel}): ${PerformanceTester.formatTime(valueB)}`);\n\n if (valueA > 0 && valueB > 0) {\n const ratio = valueA / valueB;\n const percentDiff = ((ratio - 1) * 100).toFixed(2);\n if (ratio > 1) {\n console.log(`${this.nameB} 快 ${percentDiff}% (${ratio.toFixed(2)}x)`);\n } else {\n console.log(\n `${this.nameA} 快 ${(-parseFloat(percentDiff)).toFixed(2)}% (${(1 / ratio).toFixed(2)}x)`,\n );\n }\n }\n\n // 处理新的内存数据结构(heapUsedDiff)和旧的数据结构(memoryBefore/memoryAfter)\n let memoryUsedA: number | null = null;\n let memoryUsedB: number | null = null;\n\n if (resultA.heapUsedDiff !== undefined && resultA.heapUsedDiff !== null) {\n memoryUsedA = resultA.heapUsedDiff;\n } else if (resultA.memoryBefore && resultA.memoryAfter) {\n memoryUsedA = resultA.memoryAfter.heapUsed - resultA.memoryBefore.heapUsed;\n }\n\n if (resultB.heapUsedDiff !== undefined && resultB.heapUsedDiff !== null) {\n memoryUsedB = resultB.heapUsedDiff;\n } else if (resultB.memoryBefore && resultB.memoryAfter) {\n memoryUsedB = resultB.memoryAfter.heapUsed - resultB.memoryBefore.heapUsed;\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const hasMemoryA = memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA!)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB!)}`);\n }\n\n // 只有当两个实现都有有效内存数据时才进行对比\n if (hasMemoryA && hasMemoryB && memoryUsedA! > 0 && memoryUsedB! > 0) {\n const memoryRatio = memoryUsedA! / memoryUsedB!;\n const memoryPercentDiff = ((memoryRatio - 1) * 100).toFixed(2);\n if (memoryRatio > 1) {\n console.log(`${this.nameB} 节省 ${memoryPercentDiff}% 内存`);\n } else {\n console.log(`${this.nameA} 节省 ${(-parseFloat(memoryPercentDiff)).toFixed(2)}% 内存`);\n }\n }\n }\n\n console.log('-'.repeat(80));\n }\n }\n\n /**\n * 运行完整的对比测试套件\n */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始行情状态性能对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用3次迭代取平均值,减少随机性\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 3);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 3);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '初始化测试');\n\n // 更新测试对比\n console.log('\\n运行更新测试对比...');\n const updateResultsA = [];\n const updateResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runUpdateTest(scenario.productCount, scenario.updateIterations);\n const resultB = await this.runnerB.runUpdateTest(scenario.productCount, scenario.updateIterations);\n updateResultsA.push(resultA);\n updateResultsB.push(resultB);\n } catch (error) {\n console.error(`更新对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(updateResultsA, updateResultsB, '更新测试');\n\n // 查询测试对比\n console.log('\\n运行查询测试对比...');\n const queryResultsA = [];\n const queryResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runQueryTest(scenario.productCount, scenario.queryIterations);\n const resultB = await this.runnerB.runQueryTest(scenario.productCount, scenario.queryIterations);\n queryResultsA.push(resultA);\n queryResultsB.push(resultB);\n } catch (error) {\n console.error(`查询对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(queryResultsA, queryResultsB, '查询测试');\n\n // 过滤测试对比\n console.log('\\n运行过滤测试对比...');\n const filterResultsA = [];\n const filterResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runFilterTest(scenario.productCount, scenario.filterIterations);\n const resultB = await this.runnerB.runFilterTest(scenario.productCount, scenario.filterIterations);\n filterResultsA.push(resultA);\n filterResultsB.push(resultB);\n } catch (error) {\n console.error(`过滤对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(filterResultsA, filterResultsB, '过滤测试');\n\n // 转储测试对比\n console.log('\\n运行转储测试对比...');\n const dumpResultsA = [];\n const dumpResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runDumpTest(scenario.productCount);\n const resultB = await this.runnerB.runDumpTest(scenario.productCount);\n dumpResultsA.push(resultA);\n dumpResultsB.push(resultB);\n } catch (error) {\n console.error(`转储对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(dumpResultsA, dumpResultsB, '转储测试');\n\n console.log('\\n对比测试完成!');\n }\n\n /**\n * 运行快速对比测试(仅测试小数据量)\n */\n async runQuickComparisonTest(): Promise<void> {\n console.log(`开始快速对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const quickScenarios = [\n {\n productCount: 1000,\n label: '1K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n { productCount: 10000, label: '10K', updateIterations: 10, queryIterations: 100, filterIterations: 10 },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of quickScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用2次迭代取平均值(快速测试)\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 2);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 2);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '快速初始化测试');\n\n console.log('\\n快速对比测试完成!');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"QuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/QuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteState } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { QuoteStateTestRunner } from './QuoteStateTestRunner';\n\n/**\n * 行情状态对比测试类\n * 用于比较两个不同的 IQuoteState 实现\n */\nexport class QuoteStateComparisonTest {\n private runnerA: QuoteStateTestRunner;\n private runnerB: QuoteStateTestRunner;\n private nameA: string;\n private nameB: string;\n\n constructor(\n createStateA: () => IQuoteState,\n createStateB: () => IQuoteState,\n nameA: string = '实现A',\n nameB: string = '实现B',\n ) {\n this.runnerA = new QuoteStateTestRunner(createStateA);\n this.runnerB = new QuoteStateTestRunner(createStateB);\n this.nameA = nameA;\n this.nameB = nameB;\n }\n\n /**\n * 打印对比结果\n */\n private printComparisonResults(\n resultsA: any[],\n resultsB: any[],\n testType: string,\n key: string = 'time',\n ): void {\n console.log('\\n' + '='.repeat(100));\n console.log(`行情状态性能对比测试 - ${testType}`);\n console.log('='.repeat(100));\n\n console.log(`\\n${this.nameA} vs ${this.nameB} 性能对比:`);\n console.log('-'.repeat(80));\n\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const resultA = resultsA[i];\n const resultB = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = resultA.success === false;\n const isBFailed = resultB.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${resultA.productCount || resultB.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${resultA.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${PerformanceTester.formatTime(resultA.avgTime || resultA.time)}`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${resultB.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${PerformanceTester.formatTime(resultB.avgTime || resultB.time)}`);\n }\n\n console.log('-'.repeat(80));\n continue;\n }\n\n if (resultA.productCount !== resultB.productCount) {\n console.log(`\\n⚠️ 产品数量不匹配: ${resultA.productCount} vs ${resultB.productCount}`);\n continue;\n }\n\n console.log(`\\n产品数量: ${resultA.productCount.toLocaleString()}`);\n\n // 自动检测使用哪个时间字段\n const timeKey = resultA.avgTime !== undefined ? 'avgTime' : 'time';\n const valueA = resultA[timeKey];\n const valueB = resultB[timeKey];\n\n const timeLabel = timeKey === 'avgTime' ? '平均时间' : '时间';\n console.log(`${this.nameA} (${timeLabel}): ${PerformanceTester.formatTime(valueA)}`);\n console.log(`${this.nameB} (${timeLabel}): ${PerformanceTester.formatTime(valueB)}`);\n\n if (valueA > 0 && valueB > 0) {\n const ratio = valueA / valueB;\n const percentDiff = ((ratio - 1) * 100).toFixed(2);\n if (ratio > 1) {\n console.log(`${this.nameB} 快 ${percentDiff}% (${ratio.toFixed(2)}x)`);\n } else {\n console.log(\n `${this.nameA} 快 ${(-parseFloat(percentDiff)).toFixed(2)}% (${(1 / ratio).toFixed(2)}x)`,\n );\n }\n }\n\n // 处理新的内存数据结构(heapUsedDiff)和旧的数据结构(memoryBefore/memoryAfter)\n let memoryUsedA: number | null = null;\n let memoryUsedB: number | null = null;\n\n if (resultA.heapUsedDiff !== undefined && resultA.heapUsedDiff !== null) {\n memoryUsedA = resultA.heapUsedDiff;\n } else if (resultA.memoryBefore && resultA.memoryAfter) {\n memoryUsedA = resultA.memoryAfter.heapUsed - resultA.memoryBefore.heapUsed;\n }\n\n if (resultB.heapUsedDiff !== undefined && resultB.heapUsedDiff !== null) {\n memoryUsedB = resultB.heapUsedDiff;\n } else if (resultB.memoryBefore && resultB.memoryAfter) {\n memoryUsedB = resultB.memoryAfter.heapUsed - resultB.memoryBefore.heapUsed;\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const hasMemoryA = memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== null && !isNaN(memoryUsedB);\n\n if (hasMemoryA || hasMemoryB) {\n console.log(`\\n内存使用:`);\n if (hasMemoryA) {\n console.log(`${this.nameA}: ${PerformanceTester.formatBytes(memoryUsedA!)}`);\n }\n if (hasMemoryB) {\n console.log(`${this.nameB}: ${PerformanceTester.formatBytes(memoryUsedB!)}`);\n }\n\n // 只有当两个实现都有有效内存数据时才进行对比\n if (hasMemoryA && hasMemoryB && memoryUsedA! > 0 && memoryUsedB! > 0) {\n const memoryRatio = memoryUsedA! / memoryUsedB!;\n const memoryPercentDiff = ((memoryRatio - 1) * 100).toFixed(2);\n if (memoryRatio > 1) {\n console.log(`${this.nameB} 节省 ${memoryPercentDiff}% 内存`);\n } else {\n console.log(`${this.nameA} 节省 ${(-parseFloat(memoryPercentDiff)).toFixed(2)}% 内存`);\n }\n }\n }\n\n console.log('-'.repeat(80));\n }\n }\n\n /**\n * 运行完整的对比测试套件\n */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始行情状态性能对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用3次迭代取平均值,减少随机性\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 3);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 3);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '初始化测试');\n\n // 更新测试对比\n console.log('\\n运行更新测试对比...');\n const updateResultsA = [];\n const updateResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runUpdateTest(scenario.productCount, scenario.updateIterations);\n const resultB = await this.runnerB.runUpdateTest(scenario.productCount, scenario.updateIterations);\n updateResultsA.push(resultA);\n updateResultsB.push(resultB);\n } catch (error) {\n console.error(`更新对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(updateResultsA, updateResultsB, '更新测试');\n\n // 查询测试对比\n console.log('\\n运行查询测试对比...');\n const queryResultsA = [];\n const queryResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runQueryTest(scenario.productCount, scenario.queryIterations);\n const resultB = await this.runnerB.runQueryTest(scenario.productCount, scenario.queryIterations);\n queryResultsA.push(resultA);\n queryResultsB.push(resultB);\n } catch (error) {\n console.error(`查询对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(queryResultsA, queryResultsB, '查询测试');\n\n // 过滤测试对比\n console.log('\\n运行过滤测试对比...');\n const filterResultsA = [];\n const filterResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runFilterTest(scenario.productCount, scenario.filterIterations);\n const resultB = await this.runnerB.runFilterTest(scenario.productCount, scenario.filterIterations);\n filterResultsA.push(resultA);\n filterResultsB.push(resultB);\n } catch (error) {\n console.error(`过滤对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(filterResultsA, filterResultsB, '过滤测试');\n\n // 转储测试对比\n console.log('\\n运行转储测试对比...');\n const dumpResultsA = [];\n const dumpResultsB = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const resultA = await this.runnerA.runDumpTest(scenario.productCount);\n const resultB = await this.runnerB.runDumpTest(scenario.productCount);\n dumpResultsA.push(resultA);\n dumpResultsB.push(resultB);\n } catch (error) {\n console.error(`转储对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(dumpResultsA, dumpResultsB, '转储测试');\n\n console.log('\\n对比测试完成!');\n }\n\n /**\n * 运行快速对比测试(仅测试小数据量)\n */\n async runQuickComparisonTest(): Promise<void> {\n console.log(`开始快速对比测试: ${this.nameA} vs ${this.nameB}`);\n\n const quickScenarios = [\n {\n productCount: 1000,\n label: '1K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n { productCount: 10000, label: '10K', updateIterations: 10, queryIterations: 100, filterIterations: 10 },\n ];\n\n // 初始化测试对比\n console.log('\\n运行初始化测试对比...');\n const initResultsA = [];\n const initResultsB = [];\n for (const scenario of quickScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n // 使用2次迭代取平均值(快速测试)\n const resultA = await this.runnerA.runInitializationTest(scenario.productCount, 2);\n const resultB = await this.runnerB.runInitializationTest(scenario.productCount, 2);\n initResultsA.push(resultA);\n initResultsB.push(resultB);\n } catch (error) {\n console.error(`初始化对比测试失败 (${scenario.label}):`, error);\n }\n }\n this.printComparisonResults(initResultsA, initResultsB, '快速初始化测试');\n\n console.log('\\n快速对比测试完成!');\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuoteStateTestRunner.js","sourceRoot":"","sources":["../../../src/quote/benchmark/QuoteStateTestRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { generateTestData, generateProductId, getAllFields } from './test-helpers';\n\n/**\n * 通用的行情状态测试运行器\n * 接受一个工厂函数,用于创建 IQuoteState 实例\n */\nexport class QuoteStateTestRunner {\n private fields: IQuoteKey[];\n private createState: () => IQuoteState;\n\n constructor(createState: () => IQuoteState) {\n this.createState = createState;\n this.fields = getAllFields();\n }\n\n /**\n * 运行初始化性能测试\n */\n async runInitializationTest(\n productCount: number,\n iterations: number = 1,\n ): Promise<{\n productCount: number;\n avgTime: number;\n minTime: number;\n maxTime: number;\n times: number[];\n heapUsedDiff: number | null;\n }> {\n const testData = generateTestData(productCount, this.fields);\n\n // 使用多次测量取平均值,减少随机性\n const stats = await PerformanceTester.measureTimeWithStats(() => {\n const state = this.createState();\n state.update(testData);\n return state;\n }, iterations);\n\n // 单独测量内存使用(使用更精确的方法)\n const memoryResult = await PerformanceTester.measureMemoryUsage(() => {\n const state = this.createState();\n state.update(testData);\n return state;\n });\n\n return {\n productCount,\n avgTime: stats.avgTime,\n minTime: stats.minTime,\n maxTime: stats.maxTime,\n times: stats.times,\n heapUsedDiff: memoryResult.heapUsedDiff,\n };\n }\n\n /**\n * 运行更新性能测试\n */\n async runUpdateTest(\n productCount: number,\n updateCount: number,\n ): Promise<{\n productCount: number;\n updateCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n // 生成随机更新\n const updates: IQuoteUpdateAction[] = [];\n for (let i = 0; i < updateCount; i++) {\n const update: IQuoteUpdateAction = {};\n // 随机选择一些产品和字段进行更新\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * this.fields.length);\n const field = this.fields[fieldIndex];\n\n update[productId] = {\n [field]: [(Math.random() * 1000).toFixed(4), Date.now()],\n };\n updates.push(update);\n }\n\n const result = await PerformanceTester.measureTime(() => {\n for (const update of updates) {\n state.update(update);\n }\n });\n\n return {\n productCount,\n updateCount,\n time: result.time,\n };\n }\n\n /**\n * 运行查询性能测试\n */\n async runQueryTest(\n productCount: number,\n queryCount: number,\n ): Promise<{\n productCount: number;\n queryCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n const result = await PerformanceTester.measureTime(() => {\n for (let i = 0; i < queryCount; i++) {\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * this.fields.length);\n const field = this.fields[fieldIndex];\n\n state.getValueTuple(productId, field);\n }\n });\n\n return {\n productCount,\n queryCount,\n time: result.time,\n };\n }\n\n /**\n * 运行过滤性能测试\n */\n async runFilterTest(\n productCount: number,\n filterCount: number,\n ): Promise<{\n productCount: number;\n filterCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n // 生成随机过滤条件\n const filters: { productIds: string[]; fields: IQuoteKey[]; updatedAt: number }[] = [];\n for (let i = 0; i < filterCount; i++) {\n // 随机选择1-10个产品\n const productIdsCount = Math.min(10, Math.max(1, Math.floor(Math.random() * productCount)));\n const productIds: string[] = [];\n for (let j = 0; j < productIdsCount; j++) {\n const productIndex = Math.floor(Math.random() * productCount);\n productIds.push(generateProductId(productIndex));\n }\n\n // 随机选择1-5个字段\n const fieldsCount = Math.min(5, Math.max(1, Math.floor(Math.random() * this.fields.length)));\n const fields: IQuoteKey[] = [];\n for (let j = 0; j < fieldsCount; j++) {\n const fieldIndex = Math.floor(Math.random() * this.fields.length);\n fields.push(this.fields[fieldIndex]);\n }\n\n filters.push({\n productIds,\n fields,\n updatedAt: Date.now() - Math.random() * 1000000,\n });\n }\n\n const result = await PerformanceTester.measureTime(() => {\n for (const filter of filters) {\n state.filter(filter.productIds, filter.fields, filter.updatedAt);\n }\n });\n\n return {\n productCount,\n filterCount,\n time: result.time,\n };\n }\n\n /**\n * 运行转储性能测试\n */\n async runDumpTest(productCount: number): Promise<{\n productCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n const result = await PerformanceTester.measureTime(() => {\n state.dumpAsObject();\n });\n\n return {\n productCount,\n time: result.time,\n };\n }\n\n /**\n * 打印测试结果\n */\n printResults(results: any[], testType: string, implName?: string): void {\n const nameSuffix = implName ? ` - ${implName}` : '';\n console.log('\\n' + '='.repeat(100));\n console.log(`行情状态性能测试 - ${testType}${nameSuffix}`);\n console.log('='.repeat(100));\n\n for (const result of results) {\n console.log(`\\n产品数量: ${result.productCount.toLocaleString()}`);\n\n // 处理新的数据结构(avgTime)和旧的数据结构(time)\n const displayTime = result.avgTime !== undefined ? result.avgTime : result.time;\n const timeLabel = result.avgTime !== undefined ? '平均测试时间' : '测试时间';\n\n console.log(`${timeLabel}: ${PerformanceTester.formatTime(displayTime)}`);\n\n // 如果有多重测量结果,显示范围\n if (result.minTime !== undefined && result.maxTime !== undefined) {\n console.log(\n `时间范围: ${PerformanceTester.formatTime(result.minTime)} - ${PerformanceTester.formatTime(\n result.maxTime,\n )}`,\n );\n }\n\n if (result.updateCount) {\n console.log(`更新次数: ${result.updateCount.toLocaleString()}`);\n console.log(`每次更新平均时间: ${PerformanceTester.formatTime(displayTime / result.updateCount)}`);\n }\n\n if (result.queryCount) {\n console.log(`查询次数: ${result.queryCount.toLocaleString()}`);\n console.log(`每次查询平均时间: ${PerformanceTester.formatTime(displayTime / result.queryCount)}`);\n }\n\n if (result.filterCount) {\n console.log(`过滤次数: ${result.filterCount.toLocaleString()}`);\n console.log(`每次过滤平均时间: ${PerformanceTester.formatTime(displayTime / result.filterCount)}`);\n }\n\n // 处理新的内存数据结构(heapUsedDiff)和旧的数据结构(memoryBefore/memoryAfter)\n if (result.heapUsedDiff !== undefined && result.heapUsedDiff !== null) {\n const memoryUsed = result.heapUsedDiff;\n if (isNaN(memoryUsed)) {\n console.log(`内存计算错误: heapUsedDiff=${result.heapUsedDiff}`);\n } else {\n console.log(`内存使用: ${PerformanceTester.formatBytes(memoryUsed)}`);\n console.log(`每个产品内存使用: ${PerformanceTester.formatBytes(memoryUsed / result.productCount)}`);\n }\n } else if (\n result.memoryBefore &&\n result.memoryAfter &&\n result.memoryBefore.heapUsed !== undefined &&\n result.memoryAfter.heapUsed !== undefined\n ) {\n const memoryUsed = result.memoryAfter.heapUsed - result.memoryBefore.heapUsed;\n if (isNaN(memoryUsed)) {\n console.log(\n `内存计算错误: memoryBefore.heapUsed=${result.memoryBefore.heapUsed}, memoryAfter.heapUsed=${result.memoryAfter.heapUsed}`,\n );\n } else {\n console.log(`内存使用: ${PerformanceTester.formatBytes(memoryUsed)}`);\n console.log(`每个产品内存使用: ${PerformanceTester.formatBytes(memoryUsed / result.productCount)}`);\n }\n } else if (result.memoryBefore || result.memoryAfter) {\n console.log(\n `内存数据不完整: memoryBefore=${!!result.memoryBefore}, memoryAfter=${!!result.memoryAfter}`,\n );\n }\n\n console.log('-'.repeat(80));\n }\n }\n\n /**\n * 运行完整性能测试套件\n */\n async runFullTestSuite(implName?: string): Promise<void> {\n console.log(`开始行情状态性能测试${implName ? ' - ' + implName : ''}...`);\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试\n console.log('\\n运行初始化测试...');\n const initResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runInitializationTest(scenario.productCount, 3);\n initResults.push(result);\n } catch (error) {\n console.error(`初始化测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(initResults, '初始化测试', implName);\n\n // 更新测试\n console.log('\\n运行更新测试...');\n const updateResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runUpdateTest(scenario.productCount, scenario.updateIterations);\n updateResults.push(result);\n } catch (error) {\n console.error(`更新测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(updateResults, '更新测试', implName);\n\n // 查询测试\n console.log('\\n运行查询测试...');\n const queryResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runQueryTest(scenario.productCount, scenario.queryIterations);\n queryResults.push(result);\n } catch (error) {\n console.error(`查询测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(queryResults, '查询测试', implName);\n\n // 过滤测试\n console.log('\\n运行过滤测试...');\n const filterResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runFilterTest(scenario.productCount, scenario.filterIterations);\n filterResults.push(result);\n } catch (error) {\n console.error(`过滤测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(filterResults, '过滤测试', implName);\n\n // 转储测试\n console.log('\\n运行转储测试...');\n const dumpResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runDumpTest(scenario.productCount);\n dumpResults.push(result);\n } catch (error) {\n console.error(`转储测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(dumpResults, '转储测试', implName);\n\n console.log('\\n性能测试完成!');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"QuoteStateTestRunner.js","sourceRoot":"","sources":["../../../src/quote/benchmark/QuoteStateTestRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { generateTestData, generateProductId, getAllFields } from './test-helpers';\n\n/**\n * 通用的行情状态测试运行器\n * 接受一个工厂函数,用于创建 IQuoteState 实例\n */\nexport class QuoteStateTestRunner {\n private fields: IQuoteKey[];\n private createState: () => IQuoteState;\n\n constructor(createState: () => IQuoteState) {\n this.createState = createState;\n this.fields = getAllFields();\n }\n\n /**\n * 运行初始化性能测试\n */\n async runInitializationTest(\n productCount: number,\n iterations: number = 1,\n ): Promise<{\n productCount: number;\n avgTime: number;\n minTime: number;\n maxTime: number;\n times: number[];\n heapUsedDiff: number | null;\n }> {\n const testData = generateTestData(productCount, this.fields);\n\n // 使用多次测量取平均值,减少随机性\n const stats = await PerformanceTester.measureTimeWithStats(() => {\n const state = this.createState();\n state.update(testData);\n return state;\n }, iterations);\n\n // 单独测量内存使用(使用更精确的方法)\n const memoryResult = await PerformanceTester.measureMemoryUsage(() => {\n const state = this.createState();\n state.update(testData);\n return state;\n });\n\n return {\n productCount,\n avgTime: stats.avgTime,\n minTime: stats.minTime,\n maxTime: stats.maxTime,\n times: stats.times,\n heapUsedDiff: memoryResult.heapUsedDiff,\n };\n }\n\n /**\n * 运行更新性能测试\n */\n async runUpdateTest(\n productCount: number,\n updateCount: number,\n ): Promise<{\n productCount: number;\n updateCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n // 生成随机更新\n const updates: IQuoteUpdateAction[] = [];\n for (let i = 0; i < updateCount; i++) {\n const update: IQuoteUpdateAction = {};\n // 随机选择一些产品和字段进行更新\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * this.fields.length);\n const field = this.fields[fieldIndex];\n\n update[productId] = {\n [field]: [(Math.random() * 1000).toFixed(4), Date.now()],\n };\n updates.push(update);\n }\n\n const result = await PerformanceTester.measureTime(() => {\n for (const update of updates) {\n state.update(update);\n }\n });\n\n return {\n productCount,\n updateCount,\n time: result.time,\n };\n }\n\n /**\n * 运行查询性能测试\n */\n async runQueryTest(\n productCount: number,\n queryCount: number,\n ): Promise<{\n productCount: number;\n queryCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n const result = await PerformanceTester.measureTime(() => {\n for (let i = 0; i < queryCount; i++) {\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * this.fields.length);\n const field = this.fields[fieldIndex];\n\n state.getValueTuple(productId, field);\n }\n });\n\n return {\n productCount,\n queryCount,\n time: result.time,\n };\n }\n\n /**\n * 运行过滤性能测试\n */\n async runFilterTest(\n productCount: number,\n filterCount: number,\n ): Promise<{\n productCount: number;\n filterCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n // 生成随机过滤条件\n const filters: { productIds: string[]; fields: IQuoteKey[]; updatedAt: number }[] = [];\n for (let i = 0; i < filterCount; i++) {\n // 随机选择1-10个产品\n const productIdsCount = Math.min(10, Math.max(1, Math.floor(Math.random() * productCount)));\n const productIds: string[] = [];\n for (let j = 0; j < productIdsCount; j++) {\n const productIndex = Math.floor(Math.random() * productCount);\n productIds.push(generateProductId(productIndex));\n }\n\n // 随机选择1-5个字段\n const fieldsCount = Math.min(5, Math.max(1, Math.floor(Math.random() * this.fields.length)));\n const fields: IQuoteKey[] = [];\n for (let j = 0; j < fieldsCount; j++) {\n const fieldIndex = Math.floor(Math.random() * this.fields.length);\n fields.push(this.fields[fieldIndex]);\n }\n\n filters.push({\n productIds,\n fields,\n updatedAt: Date.now() - Math.random() * 1000000,\n });\n }\n\n const result = await PerformanceTester.measureTime(() => {\n for (const filter of filters) {\n state.filter(filter.productIds, filter.fields, filter.updatedAt);\n }\n });\n\n return {\n productCount,\n filterCount,\n time: result.time,\n };\n }\n\n /**\n * 运行转储性能测试\n */\n async runDumpTest(productCount: number): Promise<{\n productCount: number;\n time: number;\n }> {\n // 创建初始状态\n const state = this.createState();\n const initialData = generateTestData(productCount, this.fields);\n state.update(initialData);\n\n const result = await PerformanceTester.measureTime(() => {\n state.dumpAsObject();\n });\n\n return {\n productCount,\n time: result.time,\n };\n }\n\n /**\n * 打印测试结果\n */\n printResults(results: any[], testType: string, implName?: string): void {\n const nameSuffix = implName ? ` - ${implName}` : '';\n console.log('\\n' + '='.repeat(100));\n console.log(`行情状态性能测试 - ${testType}${nameSuffix}`);\n console.log('='.repeat(100));\n\n for (const result of results) {\n console.log(`\\n产品数量: ${result.productCount.toLocaleString()}`);\n\n // 处理新的数据结构(avgTime)和旧的数据结构(time)\n const displayTime = result.avgTime !== undefined ? result.avgTime : result.time;\n const timeLabel = result.avgTime !== undefined ? '平均测试时间' : '测试时间';\n\n console.log(`${timeLabel}: ${PerformanceTester.formatTime(displayTime)}`);\n\n // 如果有多重测量结果,显示范围\n if (result.minTime !== undefined && result.maxTime !== undefined) {\n console.log(\n `时间范围: ${PerformanceTester.formatTime(result.minTime)} - ${PerformanceTester.formatTime(\n result.maxTime,\n )}`,\n );\n }\n\n if (result.updateCount) {\n console.log(`更新次数: ${result.updateCount.toLocaleString()}`);\n console.log(`每次更新平均时间: ${PerformanceTester.formatTime(displayTime / result.updateCount)}`);\n }\n\n if (result.queryCount) {\n console.log(`查询次数: ${result.queryCount.toLocaleString()}`);\n console.log(`每次查询平均时间: ${PerformanceTester.formatTime(displayTime / result.queryCount)}`);\n }\n\n if (result.filterCount) {\n console.log(`过滤次数: ${result.filterCount.toLocaleString()}`);\n console.log(`每次过滤平均时间: ${PerformanceTester.formatTime(displayTime / result.filterCount)}`);\n }\n\n // 处理新的内存数据结构(heapUsedDiff)和旧的数据结构(memoryBefore/memoryAfter)\n if (result.heapUsedDiff !== undefined && result.heapUsedDiff !== null) {\n const memoryUsed = result.heapUsedDiff;\n if (isNaN(memoryUsed)) {\n console.log(`内存计算错误: heapUsedDiff=${result.heapUsedDiff}`);\n } else {\n console.log(`内存使用: ${PerformanceTester.formatBytes(memoryUsed)}`);\n console.log(`每个产品内存使用: ${PerformanceTester.formatBytes(memoryUsed / result.productCount)}`);\n }\n } else if (\n result.memoryBefore &&\n result.memoryAfter &&\n result.memoryBefore.heapUsed !== undefined &&\n result.memoryAfter.heapUsed !== undefined\n ) {\n const memoryUsed = result.memoryAfter.heapUsed - result.memoryBefore.heapUsed;\n if (isNaN(memoryUsed)) {\n console.log(\n `内存计算错误: memoryBefore.heapUsed=${result.memoryBefore.heapUsed}, memoryAfter.heapUsed=${result.memoryAfter.heapUsed}`,\n );\n } else {\n console.log(`内存使用: ${PerformanceTester.formatBytes(memoryUsed)}`);\n console.log(`每个产品内存使用: ${PerformanceTester.formatBytes(memoryUsed / result.productCount)}`);\n }\n } else if (result.memoryBefore || result.memoryAfter) {\n console.log(\n `内存数据不完整: memoryBefore=${!!result.memoryBefore}, memoryAfter=${!!result.memoryAfter}`,\n );\n }\n\n console.log('-'.repeat(80));\n }\n }\n\n /**\n * 运行完整性能测试套件\n */\n async runFullTestSuite(implName?: string): Promise<void> {\n console.log(`开始行情状态性能测试${implName ? ' - ' + implName : ''}...`);\n\n const testScenarios = [\n {\n productCount: 10000,\n label: '10K',\n updateIterations: 1000,\n queryIterations: 10000,\n filterIterations: 1000,\n },\n {\n productCount: 100000,\n label: '100K',\n updateIterations: 100,\n queryIterations: 1000,\n filterIterations: 100,\n },\n {\n productCount: 1000000,\n label: '1M',\n updateIterations: 10,\n queryIterations: 100,\n filterIterations: 10,\n },\n ];\n\n // 初始化测试\n console.log('\\n运行初始化测试...');\n const initResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runInitializationTest(scenario.productCount, 3);\n initResults.push(result);\n } catch (error) {\n console.error(`初始化测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(initResults, '初始化测试', implName);\n\n // 更新测试\n console.log('\\n运行更新测试...');\n const updateResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runUpdateTest(scenario.productCount, scenario.updateIterations);\n updateResults.push(result);\n } catch (error) {\n console.error(`更新测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(updateResults, '更新测试', implName);\n\n // 查询测试\n console.log('\\n运行查询测试...');\n const queryResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runQueryTest(scenario.productCount, scenario.queryIterations);\n queryResults.push(result);\n } catch (error) {\n console.error(`查询测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(queryResults, '查询测试', implName);\n\n // 过滤测试\n console.log('\\n运行过滤测试...');\n const filterResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runFilterTest(scenario.productCount, scenario.filterIterations);\n filterResults.push(result);\n } catch (error) {\n console.error(`过滤测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(filterResults, '过滤测试', implName);\n\n // 转储测试\n console.log('\\n运行转储测试...');\n const dumpResults = [];\n for (const scenario of testScenarios) {\n console.log(`测试 ${scenario.label} 产品...`);\n try {\n const result = await this.runDumpTest(scenario.productCount);\n dumpResults.push(result);\n } catch (error) {\n console.error(`转储测试失败 (${scenario.label}):`, error);\n }\n }\n this.printResults(dumpResults, '转储测试', implName);\n\n console.log('\\n性能测试完成!');\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/quote/benchmark/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAElF,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,WAAW;AACX,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjG,WAAW;AACX,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;GAGG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/quote/benchmark/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAElF,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,WAAW;AACX,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjG,WAAW;AACX,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;GAGG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAE7C,MAAM,oBAAoB,GAAG,IAAI,8BAA8B,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEvF,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,oBAAoB,CAAC,sBAAsB,EAAE,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,MAAM,oBAAoB,CAAC,sBAAsB,EAAE,CAAC;IACtD,CAAC;AACH,CAAC;AAED,kBAAkB;AAClB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,eAAe;AACf,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport { ForkedQuoteStateComparisonTest } from './ForkedQuoteStateComparisonTest';\n\n// 导出性能测试工具类\nexport { PerformanceTester } from './PerformanceTester';\n\n// 导出测试辅助函数\nexport { generateProductId, generateTestData, getAllFields, randomString } from './test-helpers';\n\n// 导出测试运行器类\nexport { ForkedQuoteStateComparisonTest } from './ForkedQuoteStateComparisonTest';\nexport { QuoteStateComparisonTest } from './QuoteStateComparisonTest';\nexport { QuoteStateTestRunner } from './QuoteStateTestRunner';\n\n/**\n * 主函数 - 命令行入口点\n * 仅支持 --fork-compare 和 --fork-compare --quick 模式\n */\nasync function main() {\n const args = process.argv.slice(2);\n\n // 检查是否使用正确的模式\n if (!args.includes('--fork-compare')) {\n console.log('使用方法:');\n console.log(' --fork-compare 运行完整的子进程隔离内存对比测试');\n console.log(' --fork-compare --quick 运行快速的子进程隔离内存对比测试');\n console.log('');\n console.log('注意:每个实现都在独立的子进程中运行,确保内存测试的公平性');\n return;\n }\n\n // 子进程隔离内存对比测试模式\n console.log('运行子进程隔离内存对比测试模式...');\n console.log('注意:每个实现都在独立的子进程中运行,确保内存测试的公平性');\n\n const forkedComparisonTest = new ForkedQuoteStateComparisonTest('Current', 'Baseline');\n\n if (args.includes('--quick')) {\n await forkedComparisonTest.runQuickComparisonTest();\n } else {\n await forkedComparisonTest.runComparisonTestSuite();\n }\n}\n\n// 如果直接运行此文件,则执行测试\nif (require.main === module) {\n main().catch(console.error);\n}\n\n// 导出主函数以供程序化使用\nexport { main as runBenchmark };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../../src/quote/benchmark/test-helpers.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,KAAK,GAAG,gEAAgE,CAAC;IAC/E,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../../src/quote/benchmark/test-helpers.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,KAAK,GAAG,gEAAgE,CAAC;IAC/E,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,WAAW,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,4BAA4B;IAC5B,OAAO;QACL,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,YAAY;QACZ,WAAW;QACX,qBAAqB;QACrB,eAAe;QACf,+BAA+B;QAC/B,+BAA+B;QAC/B,oBAAoB;KACrB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB,EAAE,MAAmB;IACxE,MAAM,IAAI,GAAuB,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;QAErB,aAAa;QACb,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,WAAW;YACX,IAAI,KAAa,CAAC;YAClB,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtD,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;YACvD,CAAC;iBAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACxC,KAAK,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;YAED,IAAI,CAAC,SAAS,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { IQuoteKey, IQuoteUpdateAction } from '../types';\n\n/**\n * 生成随机字符串\n */\nexport function randomString(length: number): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\n/**\n * 生成随机产品ID\n */\nexport function generateProductId(index: number): string {\n return `product_${index.toString().padStart(10, '0')}`;\n}\n\n/**\n * 获取所有字段列表\n */\nexport function getAllFields(): IQuoteKey[] {\n // 从 state.ts 中的 FIELDS 数组获取\n return [\n 'last_price',\n 'ask_price',\n 'ask_volume',\n 'bid_volume',\n 'bid_price',\n 'interest_rate_short',\n 'open_interest',\n 'interest_rate_prev_settled_at',\n 'interest_rate_next_settled_at',\n 'interest_rate_long',\n ];\n}\n\n/**\n * 生成测试数据\n */\nexport function generateTestData(productCount: number, fields: IQuoteKey[]): IQuoteUpdateAction {\n const data: IQuoteUpdateAction = {};\n const now = Date.now();\n\n for (let i = 0; i < productCount; i++) {\n const productId = generateProductId(i);\n data[productId] = {};\n\n // 为每个字段生成随机值\n for (const field of fields) {\n // 生成合适的随机值\n let value: string;\n if (field.includes('price') || field.includes('rate')) {\n value = (Math.random() * 1000).toFixed(4);\n } else if (field.includes('volume') || field.includes('interest')) {\n value = Math.floor(Math.random() * 10000).toString();\n } else if (field.includes('settled_at')) {\n value = (now + Math.random() * 1000000).toFixed(0);\n } else {\n value = randomString(10);\n }\n\n data[productId]![field] = [value, now];\n }\n }\n\n return data;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/quote/benchmark/worker.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { performance } from 'perf_hooks';\nimport { implementations } from '../implementations';\nimport { IQuoteKey, IQuoteState } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { generateProductId, generateTestData, getAllFields } from './test-helpers';\n\n/**\n * 子进程测试 Worker\n * 接收命令行参数,运行指定的测试,输出 JSON 结果到 stdout\n *\n * 命令行参数格式:\n * --impl=<implName> // 实现名称:current 或 baseline\n * --test=<testType> // 测试类型:init, update, query, filter, dump\n * --product-count=<N> // 产品数量\n * --iterations=<N> // 迭代次数(可选,某些测试需要)\n * --update-count=<N> // 更新次数(update测试需要)\n * --query-count=<N> // 查询次数(query测试需要)\n * --filter-count=<N> // 过滤次数(filter测试需要)\n */\n\n// 解析命令行参数\nfunction parseArgs(): Record<string, string> {\n const args = process.argv.slice(2);\n const result: Record<string, string> = {};\n\n for (const arg of args) {\n if (arg.startsWith('--')) {\n const [key, value] = arg.slice(2).split('=');\n result[key] = value || 'true';\n }\n }\n\n return result;\n}\n\n// 运行初始化测试\nasync function runInitializationTest(\n createState: () => IQuoteState,\n productCount: number,\n iterations: number = 1,\n) {\n const fields = getAllFields();\n const testData = generateTestData(productCount, fields);\n\n const times: number[] = [];\n let finalResult: IQuoteState | undefined;\n\n for (let i = 0; i < iterations; i++) {\n const start = performance.now();\n const state = createState();\n state.update(testData);\n const end = performance.now();\n\n if (i === 0) finalResult = state;\n times.push(end - start);\n }\n\n const avgTime = times.reduce((a, b) => a + b, 0) / times.length;\n const minTime = Math.min(...times);\n const maxTime = Math.max(...times);\n\n // 单独测量内存使用\n const memoryResult = await PerformanceTester.measureMemoryUsage(() => {\n const state = createState();\n state.update(testData);\n return state;\n });\n\n return {\n productCount,\n avgTime,\n minTime,\n maxTime,\n times,\n heapUsedDiff: memoryResult.heapUsedDiff,\n };\n}\n\n// 运行更新测试\nasync function runUpdateTest(createState: () => IQuoteState, productCount: number, updateCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n // 生成随机更新\n const updates: Record<string, Partial<Record<IQuoteKey, [string, number]>>>[] = [];\n for (let i = 0; i < updateCount; i++) {\n const update: Record<string, Partial<Record<IQuoteKey, [string, number]>>> = {};\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * fields.length);\n const field = fields[fieldIndex];\n\n update[productId] = {\n [field]: [(Math.random() * 1000).toFixed(4), Date.now()],\n };\n updates.push(update);\n }\n\n const start = performance.now();\n for (const update of updates) {\n state.update(update);\n }\n const end = performance.now();\n\n return {\n productCount,\n updateCount,\n time: end - start,\n };\n}\n\n// 运行查询测试\nasync function runQueryTest(createState: () => IQuoteState, productCount: number, queryCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n const start = performance.now();\n for (let i = 0; i < queryCount; i++) {\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * fields.length);\n const field = fields[fieldIndex];\n\n state.getValueTuple(productId, field);\n }\n const end = performance.now();\n\n return {\n productCount,\n queryCount,\n time: end - start,\n };\n}\n\n// 运行过滤测试\nasync function runFilterTest(createState: () => IQuoteState, productCount: number, filterCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n // 生成随机过滤条件\n const filters: { productIds: string[]; fields: IQuoteKey[]; updatedAt: number }[] = [];\n for (let i = 0; i < filterCount; i++) {\n const productIdsCount = Math.min(10, Math.max(1, Math.floor(Math.random() * productCount)));\n const productIds: string[] = [];\n for (let j = 0; j < productIdsCount; j++) {\n const productIndex = Math.floor(Math.random() * productCount);\n productIds.push(generateProductId(productIndex));\n }\n\n const fieldsCount = Math.min(5, Math.max(1, Math.floor(Math.random() * fields.length)));\n const selectedFields: IQuoteKey[] = [];\n for (let j = 0; j < fieldsCount; j++) {\n const fieldIndex = Math.floor(Math.random() * fields.length);\n selectedFields.push(fields[fieldIndex]);\n }\n\n filters.push({\n productIds,\n fields: selectedFields,\n updatedAt: Date.now() - Math.random() * 1000000,\n });\n }\n\n const start = performance.now();\n for (const filter of filters) {\n state.filter(filter.productIds, filter.fields, filter.updatedAt);\n }\n const end = performance.now();\n\n return {\n productCount,\n filterCount,\n time: end - start,\n };\n}\n\n// 运行转储测试\nasync function runDumpTest(createState: () => IQuoteState, productCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n const start = performance.now();\n state.dumpAsObject();\n const end = performance.now();\n\n return {\n productCount,\n time: end - start,\n };\n}\n\n// 主函数\nasync function main() {\n const args = parseArgs();\n\n // 验证必要参数\n if (!args.impl) {\n console.error(JSON.stringify({ error: 'Missing required parameter: --impl' }));\n process.exit(1);\n }\n\n if (!args.test) {\n console.error(JSON.stringify({ error: 'Missing required parameter: --test' }));\n process.exit(1);\n }\n\n if (!args['product-count']) {\n console.error(JSON.stringify({ error: 'Missing required parameter: --product-count' }));\n process.exit(1);\n }\n\n const implName = args.impl;\n const testType = args.test;\n const productCount = parseInt(args['product-count'], 10);\n\n // 选择实现\n let createState: () => IQuoteState;\n if (implName === 'current') {\n createState = implementations.current;\n } else if (implName === 'baseline') {\n createState = implementations.baseline;\n } else {\n console.error(JSON.stringify({ error: `Unknown implementation: ${implName}` }));\n process.exit(1);\n }\n\n try {\n let result: any;\n\n switch (testType) {\n case 'init':\n const iterations = args.iterations ? parseInt(args.iterations, 10) : 1;\n result = await runInitializationTest(createState, productCount, iterations);\n break;\n\n case 'update':\n if (!args['update-count']) {\n console.error(\n JSON.stringify({ error: 'Missing required parameter: --update-count for update test' }),\n );\n process.exit(1);\n }\n const updateCount = parseInt(args['update-count'], 10);\n result = await runUpdateTest(createState, productCount, updateCount);\n break;\n\n case 'query':\n if (!args['query-count']) {\n console.error(\n JSON.stringify({ error: 'Missing required parameter: --query-count for query test' }),\n );\n process.exit(1);\n }\n const queryCount = parseInt(args['query-count'], 10);\n result = await runQueryTest(createState, productCount, queryCount);\n break;\n\n case 'filter':\n if (!args['filter-count']) {\n console.error(\n JSON.stringify({ error: 'Missing required parameter: --filter-count for filter test' }),\n );\n process.exit(1);\n }\n const filterCount = parseInt(args['filter-count'], 10);\n result = await runFilterTest(createState, productCount, filterCount);\n break;\n\n case 'dump':\n result = await runDumpTest(createState, productCount);\n break;\n\n default:\n console.error(JSON.stringify({ error: `Unknown test type: ${testType}` }));\n process.exit(1);\n }\n\n // 输出 JSON 结果\n const output = {\n success: true,\n impl: implName,\n test: testType,\n productCount,\n ...result,\n timestamp: Date.now(),\n };\n\n console.log(JSON.stringify(output, null, 2));\n } catch (error) {\n console.error(\n JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n impl: implName,\n test: testType,\n productCount,\n timestamp: Date.now(),\n }),\n );\n process.exit(1);\n }\n}\n\n// 如果直接运行此文件,则执行测试\nif (require.main === module) {\n main().catch((error) => {\n console.error(\n JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n timestamp: Date.now(),\n }),\n );\n process.exit(1);\n });\n}\n\nexport {};\n"]}
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/quote/benchmark/worker.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { performance } from 'perf_hooks';\nimport { implementations } from '../implementations';\nimport { IQuoteKey, IQuoteState } from '../types';\nimport { PerformanceTester } from './PerformanceTester';\nimport { generateProductId, generateTestData, getAllFields } from './test-helpers';\n\n/**\n * 子进程测试 Worker\n * 接收命令行参数,运行指定的测试,输出 JSON 结果到 stdout\n *\n * 命令行参数格式:\n * --impl=<implName> // 实现名称:current 或 baseline\n * --test=<testType> // 测试类型:init, update, query, filter, dump\n * --product-count=<N> // 产品数量\n * --iterations=<N> // 迭代次数(可选,某些测试需要)\n * --update-count=<N> // 更新次数(update测试需要)\n * --query-count=<N> // 查询次数(query测试需要)\n * --filter-count=<N> // 过滤次数(filter测试需要)\n */\n\n// 解析命令行参数\nfunction parseArgs(): Record<string, string> {\n const args = process.argv.slice(2);\n const result: Record<string, string> = {};\n\n for (const arg of args) {\n if (arg.startsWith('--')) {\n const [key, value] = arg.slice(2).split('=');\n result[key] = value || 'true';\n }\n }\n\n return result;\n}\n\n// 运行初始化测试\nasync function runInitializationTest(\n createState: () => IQuoteState,\n productCount: number,\n iterations: number = 1,\n) {\n const fields = getAllFields();\n const testData = generateTestData(productCount, fields);\n\n const times: number[] = [];\n let finalResult: IQuoteState | undefined;\n\n for (let i = 0; i < iterations; i++) {\n const start = performance.now();\n const state = createState();\n state.update(testData);\n const end = performance.now();\n\n if (i === 0) finalResult = state;\n times.push(end - start);\n }\n\n const avgTime = times.reduce((a, b) => a + b, 0) / times.length;\n const minTime = Math.min(...times);\n const maxTime = Math.max(...times);\n\n // 单独测量内存使用\n const memoryResult = await PerformanceTester.measureMemoryUsage(() => {\n const state = createState();\n state.update(testData);\n return state;\n });\n\n return {\n productCount,\n avgTime,\n minTime,\n maxTime,\n times,\n heapUsedDiff: memoryResult.heapUsedDiff,\n };\n}\n\n// 运行更新测试\nasync function runUpdateTest(createState: () => IQuoteState, productCount: number, updateCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n // 生成随机更新\n const updates: Record<string, Partial<Record<IQuoteKey, [string, number]>>>[] = [];\n for (let i = 0; i < updateCount; i++) {\n const update: Record<string, Partial<Record<IQuoteKey, [string, number]>>> = {};\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * fields.length);\n const field = fields[fieldIndex];\n\n update[productId] = {\n [field]: [(Math.random() * 1000).toFixed(4), Date.now()],\n };\n updates.push(update);\n }\n\n const start = performance.now();\n for (const update of updates) {\n state.update(update);\n }\n const end = performance.now();\n\n return {\n productCount,\n updateCount,\n time: end - start,\n };\n}\n\n// 运行查询测试\nasync function runQueryTest(createState: () => IQuoteState, productCount: number, queryCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n const start = performance.now();\n for (let i = 0; i < queryCount; i++) {\n const productIndex = Math.floor(Math.random() * productCount);\n const productId = generateProductId(productIndex);\n const fieldIndex = Math.floor(Math.random() * fields.length);\n const field = fields[fieldIndex];\n\n state.getValueTuple(productId, field);\n }\n const end = performance.now();\n\n return {\n productCount,\n queryCount,\n time: end - start,\n };\n}\n\n// 运行过滤测试\nasync function runFilterTest(createState: () => IQuoteState, productCount: number, filterCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n // 生成随机过滤条件\n const filters: { productIds: string[]; fields: IQuoteKey[]; updatedAt: number }[] = [];\n for (let i = 0; i < filterCount; i++) {\n const productIdsCount = Math.min(10, Math.max(1, Math.floor(Math.random() * productCount)));\n const productIds: string[] = [];\n for (let j = 0; j < productIdsCount; j++) {\n const productIndex = Math.floor(Math.random() * productCount);\n productIds.push(generateProductId(productIndex));\n }\n\n const fieldsCount = Math.min(5, Math.max(1, Math.floor(Math.random() * fields.length)));\n const selectedFields: IQuoteKey[] = [];\n for (let j = 0; j < fieldsCount; j++) {\n const fieldIndex = Math.floor(Math.random() * fields.length);\n selectedFields.push(fields[fieldIndex]);\n }\n\n filters.push({\n productIds,\n fields: selectedFields,\n updatedAt: Date.now() - Math.random() * 1000000,\n });\n }\n\n const start = performance.now();\n for (const filter of filters) {\n state.filter(filter.productIds, filter.fields, filter.updatedAt);\n }\n const end = performance.now();\n\n return {\n productCount,\n filterCount,\n time: end - start,\n };\n}\n\n// 运行转储测试\nasync function runDumpTest(createState: () => IQuoteState, productCount: number) {\n const fields = getAllFields();\n const state = createState();\n const initialData = generateTestData(productCount, fields);\n state.update(initialData);\n\n const start = performance.now();\n state.dumpAsObject();\n const end = performance.now();\n\n return {\n productCount,\n time: end - start,\n };\n}\n\n// 主函数\nasync function main() {\n const args = parseArgs();\n\n // 验证必要参数\n if (!args.impl) {\n console.error(JSON.stringify({ error: 'Missing required parameter: --impl' }));\n process.exit(1);\n }\n\n if (!args.test) {\n console.error(JSON.stringify({ error: 'Missing required parameter: --test' }));\n process.exit(1);\n }\n\n if (!args['product-count']) {\n console.error(JSON.stringify({ error: 'Missing required parameter: --product-count' }));\n process.exit(1);\n }\n\n const implName = args.impl;\n const testType = args.test;\n const productCount = parseInt(args['product-count'], 10);\n\n // 选择实现\n let createState: () => IQuoteState;\n if (implName === 'current') {\n createState = implementations.current;\n } else if (implName === 'baseline') {\n createState = implementations.baseline;\n } else {\n console.error(JSON.stringify({ error: `Unknown implementation: ${implName}` }));\n process.exit(1);\n }\n\n try {\n let result: any;\n\n switch (testType) {\n case 'init':\n const iterations = args.iterations ? parseInt(args.iterations, 10) : 1;\n result = await runInitializationTest(createState, productCount, iterations);\n break;\n\n case 'update':\n if (!args['update-count']) {\n console.error(\n JSON.stringify({ error: 'Missing required parameter: --update-count for update test' }),\n );\n process.exit(1);\n }\n const updateCount = parseInt(args['update-count'], 10);\n result = await runUpdateTest(createState, productCount, updateCount);\n break;\n\n case 'query':\n if (!args['query-count']) {\n console.error(\n JSON.stringify({ error: 'Missing required parameter: --query-count for query test' }),\n );\n process.exit(1);\n }\n const queryCount = parseInt(args['query-count'], 10);\n result = await runQueryTest(createState, productCount, queryCount);\n break;\n\n case 'filter':\n if (!args['filter-count']) {\n console.error(\n JSON.stringify({ error: 'Missing required parameter: --filter-count for filter test' }),\n );\n process.exit(1);\n }\n const filterCount = parseInt(args['filter-count'], 10);\n result = await runFilterTest(createState, productCount, filterCount);\n break;\n\n case 'dump':\n result = await runDumpTest(createState, productCount);\n break;\n\n default:\n console.error(JSON.stringify({ error: `Unknown test type: ${testType}` }));\n process.exit(1);\n }\n\n // 输出 JSON 结果\n const output = {\n success: true,\n impl: implName,\n test: testType,\n productCount,\n ...result,\n timestamp: Date.now(),\n };\n\n console.log(JSON.stringify(output, null, 2));\n } catch (error) {\n console.error(\n JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n impl: implName,\n test: testType,\n productCount,\n timestamp: Date.now(),\n }),\n );\n process.exit(1);\n }\n}\n\n// 如果直接运行此文件,则执行测试\nif (require.main === module) {\n main().catch((error) => {\n console.error(\n JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n timestamp: Date.now(),\n }),\n );\n process.exit(1);\n });\n}\n\nexport {};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v0.js","sourceRoot":"","sources":["../../../src/quote/implementations/v0.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,sDAAsD;IACtD,MAAM,IAAI,GAAG,IAAI,GAAG,EAA4C,CAAC;IAEjE,MAAM,MAAM,GAAG,CAAC,MAA0B,EAAE,EAAE;QAC5C,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"v0.js","sourceRoot":"","sources":["../../../src/quote/implementations/v0.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\n\n/**\n * 创建一个简单的基于 Map 的实现,用于对比测试\n * 这个实现使用嵌套 Map 结构,作为性能对比的基准\n */\nexport function createQuoteStateV0(): IQuoteState {\n // 使用三层嵌套结构:product_id -> field -> [value, updated_at]\n const data = new Map<string, Map<IQuoteKey, [string, number]>>();\n\n const update = (action: IQuoteUpdateAction) => {\n for (const product_id in action) {\n let productMap = data.get(product_id);\n if (!productMap) {\n productMap = new Map();\n data.set(product_id, productMap);\n }\n\n const fields = action[product_id];\n for (const field_name in fields) {\n const field = field_name as IQuoteKey;\n const [value, updated_at] = fields[field]!;\n const existing = productMap.get(field);\n if (!existing || updated_at >= existing[1]) {\n productMap.set(field, [value, updated_at]);\n }\n }\n }\n };\n\n const dumpAsObject = (): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n data.forEach((productMap, product_id) => {\n const productData: Partial<Record<IQuoteKey, [string, number]>> = {};\n productMap.forEach((tuple, field) => {\n productData[field] = tuple;\n });\n result[product_id] = productData;\n });\n return result;\n };\n\n const getValueTuple = (product_id: string, field: IQuoteKey): [string, number] | undefined => {\n const productMap = data.get(product_id);\n if (!productMap) return undefined;\n return productMap.get(field);\n };\n\n const filter = (product_ids: string[], fields: IQuoteKey[], updated_at: number): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n for (const product_id of product_ids) {\n const productMap = data.get(product_id);\n const productData: Partial<Record<IQuoteKey, [string, number]>> = {};\n\n if (productMap) {\n for (const field of fields) {\n const tuple = productMap.get(field);\n if (tuple && tuple[1] >= updated_at) {\n productData[field] = tuple;\n }\n }\n }\n\n result[product_id] = productData;\n }\n return result;\n };\n\n const filterValues = <K extends IQuoteKey>(\n product_ids: string[],\n fields: K[],\n ): Record<string, Record<K, string>> => {\n const result: Record<string, Record<K, string>> = {};\n for (const product_id of product_ids) {\n result[product_id] = {} as Record<K, string>;\n for (const field of fields) {\n const tuple = getValueTuple(product_id, field);\n result[product_id][field] = tuple ? tuple[0] : '';\n }\n }\n return result;\n };\n\n return { update, dumpAsObject, getValueTuple, filter, filterValues };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v1.js","sourceRoot":"","sources":["../../../src/quote/implementations/v1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAwB;AACxB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAiC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAiB,CAAC,CAAC;IAC3F,mDAAmD;IACnD,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,mBAAmB,EAAE,CAAC;IACtB,aAAa,EAAE,CAAC;IAChB,6BAA6B,EAAE,CAAC;IAChC,6BAA6B,EAAE,CAAC;IAChC,kBAAkB,EAAE,CAAC;IACrB,iCAAiC,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;AAClC,MAAM,oBAAoB,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAElG;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAgB,EAAE;IAClD,+BAA+B;IAC/B,MAAM,IAAI,GAAwB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtD,2CAA2C;IAC3C,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAE,KAAa,EAAsB,EAAE;QAC/E,IAAI,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,SAAS,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"v1.js","sourceRoot":"","sources":["../../../src/quote/implementations/v1.ts"],"names":[],"mappings":"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","sourcesContent":["import { newError } from '@yuants/utils';\nimport { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\n\n// TRICK: 固定字段顺序,方便计算偏移量\nconst FIELDS = ((x: { [key in IQuoteKey]: number }) => Object.keys(x).sort() as IQuoteKey[])({\n // TS TRICK: 强制运行时数组具有 IQuoteKey 的所有字段。不重不漏,味道真是好极了\n last_price: 0,\n ask_price: 0,\n ask_volume: 0,\n bid_volume: 0,\n bid_price: 0,\n interest_rate_short: 0,\n open_interest: 0,\n interest_rate_prev_settled_at: 0,\n interest_rate_next_settled_at: 0,\n interest_rate_long: 0,\n interest_rate_settlement_interval: 0,\n});\n\nconst FIELD_COUNT = FIELDS.length;\nconst mapFieldNameToOffset = Object.fromEntries(FIELDS.map((field, index) => [field, index * 2]));\n\n/**\n * 高效的行情状态管理器\n * 内部使用扁平化数组存储数据,避免内存碎片化和过多的 Map/对象开销\n * 提供高效的读写接口,支持按需更新和查询\n */\nexport const createQuoteStateV1 = (): IQuoteState => {\n // 内部数据结构的设计需要考虑高效的读写性能,防止内存碎片化\n const data: (string | number)[] = [];\n const products: string[] = [];\n const mapProductIdToIndex = new Map<string, number>();\n // 0~20 (10 fields * 2 (value, updated_at))\n const getFieldOffset = (product_id: string, field: string): number | undefined => {\n let baseIndex = mapProductIdToIndex.get(product_id);\n if (baseIndex === undefined) {\n return undefined;\n }\n const fieldOffset = mapFieldNameToOffset[field];\n if (fieldOffset === undefined) throw newError('INVALID_FIELD_NAME', { field, available_fields: FIELDS });\n return baseIndex + fieldOffset;\n };\n\n const getValueTuple = (product_id: string, field: IQuoteKey): [string, number] | undefined => {\n const offset = getFieldOffset(product_id, field);\n if (offset === undefined) return undefined;\n const value = data[offset] as string;\n if (value === undefined) return undefined;\n const updated_at = data[offset + 1] as number;\n return [value, updated_at];\n };\n\n const setValueTuple = (product_id: string, field: IQuoteKey, value: string, updated_at: number) => {\n let offset = getFieldOffset(product_id, field);\n if (offset === undefined) {\n const baseIndex = mapProductIdToIndex.size * FIELD_COUNT * 2;\n products.push(product_id);\n mapProductIdToIndex.set(product_id, baseIndex);\n offset = baseIndex + mapFieldNameToOffset[field];\n }\n data[offset] = value;\n data[offset + 1] = updated_at;\n };\n\n const update = (action: IQuoteUpdateAction) => {\n for (const product_id in action) {\n const fields = action[product_id];\n for (const field_name in fields) {\n const field = field_name as IQuoteKey;\n const [value, updated_at] = fields[field]!;\n const oldTuple = getValueTuple(product_id, field);\n if (oldTuple === undefined || updated_at >= oldTuple[1]) {\n setValueTuple(product_id, field, value, updated_at);\n }\n }\n }\n };\n\n const dumpAsObject = (): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n for (const product_id of products) {\n result[product_id] = {};\n }\n for (let i = 0; i < data.length; i += 2) {\n const value = data[i] as string;\n if (value === undefined) continue;\n const updated_at = data[i + 1] as number;\n\n const productIndex = Math.floor(i / (FIELD_COUNT * 2));\n const product_id = products[productIndex];\n\n const fieldIndex = (i % (FIELD_COUNT * 2)) / 2;\n const field_name = FIELDS[fieldIndex];\n\n result[product_id][field_name] = [value, updated_at];\n }\n return result;\n };\n\n /**\n * 过滤状态,返回指定 product_id 列表和字段列表中,且更新时间不早于指定时间的字段数据\n * @param product_ids - 需要过滤的 product_id 列表\n * @param fields - 需要过滤的字段列表\n * @param updated_at - 需要过滤的更新时间阈值 (仅返回更新时间不早于该值的字段)\n * @returns 过滤后的数据\n */\n const filter = (product_ids: string[], fields: IQuoteKey[], updated_at: number): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n for (const product_id of product_ids) {\n result[product_id] = {};\n for (const field of fields) {\n const tuple = getValueTuple(product_id, field);\n if (tuple && tuple[1] >= updated_at) {\n result[product_id]![field] = tuple;\n }\n }\n }\n return result;\n };\n\n const filterValues = <K extends IQuoteKey>(\n product_ids: string[],\n fields: K[],\n ): Record<string, Record<K, string>> => {\n const result: Record<string, Record<K, string>> = {};\n for (const product_id of product_ids) {\n result[product_id] = {} as Record<K, string>;\n for (const field of fields) {\n const offset = getFieldOffset(product_id, field);\n if (offset === undefined) {\n result[product_id][field] = '';\n } else {\n result[product_id][field] = (data[offset] as string) || '';\n }\n }\n }\n return result;\n };\n\n return { update, dumpAsObject, getValueTuple, filter, filterValues };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../../../src/quote/implementations/v2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAwB;AACxB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAiC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAiB,CAAC,CAAC;IAC3F,mDAAmD;IACnD,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,CAAC;IACZ,mBAAmB,EAAE,CAAC;IACtB,aAAa,EAAE,CAAC;IAChB,6BAA6B,EAAE,CAAC;IAChC,6BAA6B,EAAE,CAAC;IAChC,kBAAkB,EAAE,CAAC;IACrB,iCAAiC,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;AAClC,MAAM,oBAAoB,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;AAExG;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAgB,EAAE;IAClD,+BAA+B;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC,CAAC,QAAQ;IACrC,MAAM,UAAU,GAAa,EAAE,CAAC,CAAC,UAAU;IAC3C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtD,yBAAyB;IACzB,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAE,KAAa,EAAU,EAAE;QACnE,IAAI,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,SAAS,KAAK,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../../../src/quote/implementations/v2.ts"],"names":[],"mappings":"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","sourcesContent":["import { newError } from '@yuants/utils';\nimport { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\n\n// TRICK: 固定字段顺序,方便计算偏移量\nconst FIELDS = ((x: { [key in IQuoteKey]: number }) => Object.keys(x).sort() as IQuoteKey[])({\n // TS TRICK: 强制运行时数组具有 IQuoteKey 的所有字段。不重不漏,味道真是好极了\n last_price: 0,\n ask_price: 0,\n ask_volume: 0,\n bid_volume: 0,\n bid_price: 0,\n interest_rate_short: 0,\n open_interest: 0,\n interest_rate_prev_settled_at: 0,\n interest_rate_next_settled_at: 0,\n interest_rate_long: 0,\n interest_rate_settlement_interval: 0,\n});\n\nconst FIELD_COUNT = FIELDS.length;\nconst mapFieldNameToOffset = Object.fromEntries(FIELDS.map((field, index) => [field, index])); // 改为单倍偏移\n\n/**\n * 高效的行情状态管理器 v2\n * 将 value 和 timestamp 拆分为两个数组,使数组元素类型一致,提高内存访问效率\n */\nexport const createQuoteStateV2 = (): IQuoteState => {\n // 内部数据结构的设计需要考虑高效的读写性能,防止内存碎片化\n const values: string[] = []; // 存储字段值\n const timestamps: number[] = []; // 存储更新时间戳\n const products: string[] = [];\n const mapProductIdToIndex = new Map<string, number>();\n // 每个产品占用 FIELD_COUNT 个位置\n const getFieldOffset = (product_id: string, field: string): number => {\n let baseIndex = mapProductIdToIndex.get(product_id);\n if (baseIndex === undefined) {\n baseIndex = mapProductIdToIndex.size * FIELD_COUNT;\n products.push(product_id);\n mapProductIdToIndex.set(product_id, baseIndex);\n }\n const fieldOffset = mapFieldNameToOffset[field];\n if (fieldOffset === undefined) throw newError('INVALID_FIELD_NAME', { field, available_fields: FIELDS });\n return baseIndex + fieldOffset;\n };\n\n const getValueTuple = (product_id: string, field: IQuoteKey): [string, number] | undefined => {\n const offset = getFieldOffset(product_id, field);\n const value = values[offset];\n if (value === undefined) return undefined;\n const updated_at = timestamps[offset];\n return [value, updated_at];\n };\n\n const setValueTuple = (product_id: string, field: IQuoteKey, value: string, updated_at: number) => {\n const offset = getFieldOffset(product_id, field);\n values[offset] = value;\n timestamps[offset] = updated_at;\n };\n\n const update = (action: IQuoteUpdateAction) => {\n for (const product_id in action) {\n const fields = action[product_id];\n for (const field_name in fields) {\n const field = field_name as IQuoteKey;\n const [value, updated_at] = fields[field]!;\n const oldTuple = getValueTuple(product_id, field);\n\n if (oldTuple === undefined || updated_at >= oldTuple[1]) {\n setValueTuple(product_id, field, value, updated_at);\n }\n }\n }\n };\n\n const dumpAsObject = (): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n for (const product_id of products) {\n result[product_id] = {};\n }\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n if (value === undefined) continue;\n const updated_at = timestamps[i];\n\n const productIndex = Math.floor(i / FIELD_COUNT);\n const product_id = products[productIndex];\n\n const fieldIndex = i % FIELD_COUNT;\n const field_name = FIELDS[fieldIndex];\n\n result[product_id]![field_name] = [value, updated_at];\n }\n return result;\n };\n\n /**\n * 过滤状态,返回指定 product_id 列表和字段列表中,且更新时间不早于指定时间的字段数据\n * @param product_ids - 需要过滤的 product_id 列表\n * @param fields - 需要过滤的字段列表\n * @param updated_at - 需要过滤的更新时间阈值 (仅返回更新时间不早于该值的字段)\n * @returns 过滤后的数据\n */\n const filter = (product_ids: string[], fields: IQuoteKey[], updated_at: number): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n for (const product_id of product_ids) {\n result[product_id] = {};\n for (const field of fields) {\n const tuple = getValueTuple(product_id, field);\n if (tuple && tuple[1] >= updated_at) {\n result[product_id]![field] = tuple;\n }\n }\n }\n return result;\n };\n\n const filterValues = <K extends IQuoteKey>(\n product_ids: string[],\n fields: K[],\n ): Record<string, Record<K, string>> => {\n const result: Record<string, Record<K, string>> = {};\n for (const product_id of product_ids) {\n result[product_id] = {} as Record<K, string>;\n for (const field of fields) {\n const tuple = getValueTuple(product_id, field);\n result[product_id][field] = tuple ? tuple[0] : '';\n }\n }\n return result;\n };\n\n return { update, dumpAsObject, getValueTuple, filter, filterValues };\n};\n"]}
|
|
@@ -202,7 +202,7 @@ export const createQuoteStateV3 = () => {
|
|
|
202
202
|
activeStrings: stringPool.length - freeIndices.length,
|
|
203
203
|
freeIndices: freeIndices.length,
|
|
204
204
|
memoryEstimate: {
|
|
205
|
-
data: data.length * 8,
|
|
205
|
+
data: data.length * 8, // Float64Array 每个元素8字节
|
|
206
206
|
pool: stringPool.reduce((sum, str) => sum + (str ? str.length * 2 : 0), 0),
|
|
207
207
|
structures: products.length * 50 + stringPool.length * 16, // 粗略估计
|
|
208
208
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v3.js","sourceRoot":"","sources":["../../../src/quote/implementations/v3.ts"],"names":[],"mappings":"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","sourcesContent":["import { newError } from '@yuants/utils';\nimport { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\n\n// TRICK: 固定字段顺序,方便计算偏移量\nconst FIELDS = ((x: { [key in IQuoteKey]: number }) => Object.keys(x).sort() as IQuoteKey[])({\n // TS TRICK: 强制运行时数组具有 IQuoteKey 的所有字段。不重不漏,味道真是好极了\n last_price: 0,\n ask_price: 0,\n ask_volume: 0,\n bid_volume: 0,\n bid_price: 0,\n interest_rate_short: 0,\n open_interest: 0,\n interest_rate_prev_settled_at: 0,\n interest_rate_next_settled_at: 0,\n interest_rate_long: 0,\n interest_rate_settlement_interval: 0,\n});\n\nconst FIELD_COUNT = FIELDS.length;\nconst mapFieldNameToOffset = Object.fromEntries(FIELDS.map((field, index) => [field, index * 2])); // 每个字段占2个位置: [池索引, 时间戳]\n\n/**\n * 使用引用计数字符串池的行情状态管理器 v3\n * 保持 v1 的内存局部性,同时通过字符串池减少内存开销\n * 使用 Float64Array 连续存储 [池索引, 时间戳] 对\n */\nexport const createQuoteStateV3 = (): IQuoteState => {\n // 核心数据存储:连续存储 [池索引, 时间戳, 池索引, 时间戳...]\n let data: Float64Array = new Float64Array(1024 * FIELD_COUNT * 2); // 初始容量:1024产品\n let dataLength = 0; // 当前已分配的数据槽数量(以字段为单位)\n\n // 字符串池\n let stringPool: (string | undefined)[] = []; // 索引 -> 字符串(undefined 表示空闲)\n let refCounts: number[] = []; // 索引 -> 引用计数\n let stringToIndex = new Map<string, number>(); // 字符串 -> 索引\n let freeIndices: number[] = []; // 空闲索引列表\n\n const products: string[] = [];\n const mapProductIdToIndex = new Map<string, number>();\n\n // 确保 data 有足够容量\n const ensureDataCapacity = (requiredFields: number) => {\n if (requiredFields * 2 <= data.length) return;\n\n // 倍增扩容\n const newSize = Math.max(data.length * 2, requiredFields * 2 + 1024);\n const newData = new Float64Array(newSize);\n newData.set(data);\n data = newData;\n };\n\n // 获取字段偏移量(以 Float64 元素为单位)\n const getFieldOffset = (product_id: string, field: string): number => {\n let baseIndex = mapProductIdToIndex.get(product_id);\n if (baseIndex === undefined) {\n baseIndex = mapProductIdToIndex.size;\n products.push(product_id);\n mapProductIdToIndex.set(product_id, baseIndex);\n\n // 确保有足够空间存储该产品的所有字段\n const requiredFields = (baseIndex + 1) * FIELD_COUNT;\n ensureDataCapacity(requiredFields);\n\n // 初始化该产品的所有字段为 [-1, 0](空值)\n const startIdx = baseIndex * FIELD_COUNT * 2;\n for (let i = 0; i < FIELD_COUNT * 2; i += 2) {\n data[startIdx + i] = -1; // 池索引:-1 表示空值\n data[startIdx + i + 1] = 0; // 时间戳:0\n }\n dataLength = Math.max(dataLength, requiredFields);\n }\n const fieldOffset = mapFieldNameToOffset[field];\n if (fieldOffset === undefined) throw newError('INVALID_FIELD_NAME', { field, available_fields: FIELDS });\n return baseIndex * FIELD_COUNT * 2 + fieldOffset;\n };\n\n // 获取或分配字符串索引(增加引用计数)\n const acquireStringIndex = (value: string): number => {\n let index = stringToIndex.get(value);\n if (index !== undefined) {\n // 字符串已存在,增加引用计数\n refCounts[index]++;\n return index;\n }\n\n // 需要新索引\n if (freeIndices.length > 0) {\n // 重用空闲索引\n index = freeIndices.pop()!;\n stringPool[index] = value;\n refCounts[index] = 1;\n } else {\n // 分配新索引\n index = stringPool.length;\n stringPool.push(value);\n refCounts.push(1);\n }\n\n stringToIndex.set(value, index);\n return index;\n };\n\n // 释放字符串索引(减少引用计数)\n const releaseStringIndex = (index: number): void => {\n if (index === -1) return; // 空值索引\n\n refCounts[index]--;\n if (refCounts[index] === 0) {\n // 引用计数归零,可以回收\n const value = stringPool[index]!;\n stringToIndex.delete(value);\n // 清空池中的引用,允许 GC\n stringPool[index] = undefined;\n refCounts[index] = 0;\n freeIndices.push(index);\n }\n };\n\n const getValueTuple = (product_id: string, field: IQuoteKey): [string, number] | undefined => {\n const offset = getFieldOffset(product_id, field);\n const poolIndex = data[offset];\n if (poolIndex === -1) return undefined;\n\n const timestamp = data[offset + 1];\n const value = stringPool[poolIndex]!;\n return [value, timestamp];\n };\n\n const setValueTuple = (product_id: string, field: IQuoteKey, value: string, updated_at: number) => {\n const offset = getFieldOffset(product_id, field);\n const oldPoolIndex = data[offset];\n\n // 释放旧字符串的引用\n releaseStringIndex(oldPoolIndex);\n\n // 获取新字符串索引\n const newPoolIndex = acquireStringIndex(value);\n\n // 更新存储\n data[offset] = newPoolIndex;\n data[offset + 1] = updated_at;\n };\n\n const update = (action: IQuoteUpdateAction) => {\n for (const product_id in action) {\n const fields = action[product_id];\n for (const field_name in fields) {\n const field = field_name as IQuoteKey;\n const [value, updated_at] = fields[field]!;\n const oldTuple = getValueTuple(product_id, field);\n if (oldTuple === undefined || updated_at >= oldTuple[1]) {\n setValueTuple(product_id, field, value, updated_at);\n }\n }\n }\n };\n\n const dumpAsObject = (): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n\n // 初始化所有产品的结构\n for (const product_id of products) {\n result[product_id] = {};\n }\n\n // 遍历所有字段(dataLength 是以字段为单位)\n for (let fieldIdx = 0; fieldIdx < dataLength; fieldIdx++) {\n const poolIndex = data[fieldIdx * 2];\n if (poolIndex === -1) continue; // 空值\n\n const timestamp = data[fieldIdx * 2 + 1];\n const productIndex = Math.floor(fieldIdx / FIELD_COUNT);\n const product_id = products[productIndex];\n\n const fieldIndex = fieldIdx % FIELD_COUNT;\n const field_name = FIELDS[fieldIndex];\n\n const value = stringPool[poolIndex]!;\n result[product_id]![field_name] = [value, timestamp];\n }\n\n return result;\n };\n\n /**\n * 过滤状态,返回指定 product_id 列表和字段列表中,且更新时间不早于指定时间的字段数据\n * @param product_ids - 需要过滤的 product_id 列表\n * @param fields - 需要过滤的字段列表\n * @param updated_at - 需要过滤的更新时间阈值 (仅返回更新时间不早于该值的字段)\n * @returns 过滤后的数据\n */\n const filter = (product_ids: string[], fields: IQuoteKey[], updated_at: number): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n\n for (const product_id of product_ids) {\n const productIndex = mapProductIdToIndex.get(product_id);\n if (productIndex === undefined) {\n // 产品不存在,创建空对象\n result[product_id] = {};\n continue;\n }\n\n const productResult: Partial<Record<IQuoteKey, [string, number]>> = {};\n const baseOffset = productIndex * FIELD_COUNT * 2;\n\n for (const field of fields) {\n const fieldOffset = mapFieldNameToOffset[field];\n if (fieldOffset === undefined) continue;\n\n const offset = baseOffset + fieldOffset;\n const poolIndex = data[offset];\n if (poolIndex === -1) continue; // 空值\n\n const timestamp = data[offset + 1];\n if (timestamp < updated_at) continue; // 时间戳太旧\n\n const value = stringPool[poolIndex]!;\n productResult[field] = [value, timestamp];\n }\n\n result[product_id] = productResult;\n }\n\n return result;\n };\n\n // 导出内部统计信息用于调试\n const getStats = () => ({\n productCount: products.length,\n fieldCount: dataLength,\n stringPoolSize: stringPool.length,\n activeStrings: stringPool.length - freeIndices.length,\n freeIndices: freeIndices.length,\n memoryEstimate: {\n data: data.length * 8, // Float64Array 每个元素8字节\n pool: stringPool.reduce((sum, str) => sum + (str ? str.length * 2 : 0), 0),\n structures: products.length * 50 + stringPool.length * 16, // 粗略估计\n },\n });\n\n const filterValues = <K extends IQuoteKey>(\n product_ids: string[],\n fields: K[],\n ): Record<string, Record<K, string>> => {\n const result: Record<string, Record<K, string>> = {};\n for (const product_id of product_ids) {\n result[product_id] = {} as Record<K, string>;\n for (const field of fields) {\n const tuple = getValueTuple(product_id, field);\n result[product_id][field] = tuple ? tuple[0] : '';\n }\n }\n return result;\n };\n\n return { update, dumpAsObject, getValueTuple, filter, filterValues };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"v3.js","sourceRoot":"","sources":["../../../src/quote/implementations/v3.ts"],"names":[],"mappings":"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","sourcesContent":["import { newError } from '@yuants/utils';\nimport { IQuoteKey, IQuoteState, IQuoteUpdateAction } from '../types';\n\n// TRICK: 固定字段顺序,方便计算偏移量\nconst FIELDS = ((x: { [key in IQuoteKey]: number }) => Object.keys(x).sort() as IQuoteKey[])({\n // TS TRICK: 强制运行时数组具有 IQuoteKey 的所有字段。不重不漏,味道真是好极了\n last_price: 0,\n ask_price: 0,\n ask_volume: 0,\n bid_volume: 0,\n bid_price: 0,\n interest_rate_short: 0,\n open_interest: 0,\n interest_rate_prev_settled_at: 0,\n interest_rate_next_settled_at: 0,\n interest_rate_long: 0,\n interest_rate_settlement_interval: 0,\n});\n\nconst FIELD_COUNT = FIELDS.length;\nconst mapFieldNameToOffset = Object.fromEntries(FIELDS.map((field, index) => [field, index * 2])); // 每个字段占2个位置: [池索引, 时间戳]\n\n/**\n * 使用引用计数字符串池的行情状态管理器 v3\n * 保持 v1 的内存局部性,同时通过字符串池减少内存开销\n * 使用 Float64Array 连续存储 [池索引, 时间戳] 对\n */\nexport const createQuoteStateV3 = (): IQuoteState => {\n // 核心数据存储:连续存储 [池索引, 时间戳, 池索引, 时间戳...]\n let data: Float64Array = new Float64Array(1024 * FIELD_COUNT * 2); // 初始容量:1024产品\n let dataLength = 0; // 当前已分配的数据槽数量(以字段为单位)\n\n // 字符串池\n let stringPool: (string | undefined)[] = []; // 索引 -> 字符串(undefined 表示空闲)\n let refCounts: number[] = []; // 索引 -> 引用计数\n let stringToIndex = new Map<string, number>(); // 字符串 -> 索引\n let freeIndices: number[] = []; // 空闲索引列表\n\n const products: string[] = [];\n const mapProductIdToIndex = new Map<string, number>();\n\n // 确保 data 有足够容量\n const ensureDataCapacity = (requiredFields: number) => {\n if (requiredFields * 2 <= data.length) return;\n\n // 倍增扩容\n const newSize = Math.max(data.length * 2, requiredFields * 2 + 1024);\n const newData = new Float64Array(newSize);\n newData.set(data);\n data = newData;\n };\n\n // 获取字段偏移量(以 Float64 元素为单位)\n const getFieldOffset = (product_id: string, field: string): number => {\n let baseIndex = mapProductIdToIndex.get(product_id);\n if (baseIndex === undefined) {\n baseIndex = mapProductIdToIndex.size;\n products.push(product_id);\n mapProductIdToIndex.set(product_id, baseIndex);\n\n // 确保有足够空间存储该产品的所有字段\n const requiredFields = (baseIndex + 1) * FIELD_COUNT;\n ensureDataCapacity(requiredFields);\n\n // 初始化该产品的所有字段为 [-1, 0](空值)\n const startIdx = baseIndex * FIELD_COUNT * 2;\n for (let i = 0; i < FIELD_COUNT * 2; i += 2) {\n data[startIdx + i] = -1; // 池索引:-1 表示空值\n data[startIdx + i + 1] = 0; // 时间戳:0\n }\n dataLength = Math.max(dataLength, requiredFields);\n }\n const fieldOffset = mapFieldNameToOffset[field];\n if (fieldOffset === undefined) throw newError('INVALID_FIELD_NAME', { field, available_fields: FIELDS });\n return baseIndex * FIELD_COUNT * 2 + fieldOffset;\n };\n\n // 获取或分配字符串索引(增加引用计数)\n const acquireStringIndex = (value: string): number => {\n let index = stringToIndex.get(value);\n if (index !== undefined) {\n // 字符串已存在,增加引用计数\n refCounts[index]++;\n return index;\n }\n\n // 需要新索引\n if (freeIndices.length > 0) {\n // 重用空闲索引\n index = freeIndices.pop()!;\n stringPool[index] = value;\n refCounts[index] = 1;\n } else {\n // 分配新索引\n index = stringPool.length;\n stringPool.push(value);\n refCounts.push(1);\n }\n\n stringToIndex.set(value, index);\n return index;\n };\n\n // 释放字符串索引(减少引用计数)\n const releaseStringIndex = (index: number): void => {\n if (index === -1) return; // 空值索引\n\n refCounts[index]--;\n if (refCounts[index] === 0) {\n // 引用计数归零,可以回收\n const value = stringPool[index]!;\n stringToIndex.delete(value);\n // 清空池中的引用,允许 GC\n stringPool[index] = undefined;\n refCounts[index] = 0;\n freeIndices.push(index);\n }\n };\n\n const getValueTuple = (product_id: string, field: IQuoteKey): [string, number] | undefined => {\n const offset = getFieldOffset(product_id, field);\n const poolIndex = data[offset];\n if (poolIndex === -1) return undefined;\n\n const timestamp = data[offset + 1];\n const value = stringPool[poolIndex]!;\n return [value, timestamp];\n };\n\n const setValueTuple = (product_id: string, field: IQuoteKey, value: string, updated_at: number) => {\n const offset = getFieldOffset(product_id, field);\n const oldPoolIndex = data[offset];\n\n // 释放旧字符串的引用\n releaseStringIndex(oldPoolIndex);\n\n // 获取新字符串索引\n const newPoolIndex = acquireStringIndex(value);\n\n // 更新存储\n data[offset] = newPoolIndex;\n data[offset + 1] = updated_at;\n };\n\n const update = (action: IQuoteUpdateAction) => {\n for (const product_id in action) {\n const fields = action[product_id];\n for (const field_name in fields) {\n const field = field_name as IQuoteKey;\n const [value, updated_at] = fields[field]!;\n const oldTuple = getValueTuple(product_id, field);\n if (oldTuple === undefined || updated_at >= oldTuple[1]) {\n setValueTuple(product_id, field, value, updated_at);\n }\n }\n }\n };\n\n const dumpAsObject = (): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n\n // 初始化所有产品的结构\n for (const product_id of products) {\n result[product_id] = {};\n }\n\n // 遍历所有字段(dataLength 是以字段为单位)\n for (let fieldIdx = 0; fieldIdx < dataLength; fieldIdx++) {\n const poolIndex = data[fieldIdx * 2];\n if (poolIndex === -1) continue; // 空值\n\n const timestamp = data[fieldIdx * 2 + 1];\n const productIndex = Math.floor(fieldIdx / FIELD_COUNT);\n const product_id = products[productIndex];\n\n const fieldIndex = fieldIdx % FIELD_COUNT;\n const field_name = FIELDS[fieldIndex];\n\n const value = stringPool[poolIndex]!;\n result[product_id]![field_name] = [value, timestamp];\n }\n\n return result;\n };\n\n /**\n * 过滤状态,返回指定 product_id 列表和字段列表中,且更新时间不早于指定时间的字段数据\n * @param product_ids - 需要过滤的 product_id 列表\n * @param fields - 需要过滤的字段列表\n * @param updated_at - 需要过滤的更新时间阈值 (仅返回更新时间不早于该值的字段)\n * @returns 过滤后的数据\n */\n const filter = (product_ids: string[], fields: IQuoteKey[], updated_at: number): IQuoteUpdateAction => {\n const result: IQuoteUpdateAction = {};\n\n for (const product_id of product_ids) {\n const productIndex = mapProductIdToIndex.get(product_id);\n if (productIndex === undefined) {\n // 产品不存在,创建空对象\n result[product_id] = {};\n continue;\n }\n\n const productResult: Partial<Record<IQuoteKey, [string, number]>> = {};\n const baseOffset = productIndex * FIELD_COUNT * 2;\n\n for (const field of fields) {\n const fieldOffset = mapFieldNameToOffset[field];\n if (fieldOffset === undefined) continue;\n\n const offset = baseOffset + fieldOffset;\n const poolIndex = data[offset];\n if (poolIndex === -1) continue; // 空值\n\n const timestamp = data[offset + 1];\n if (timestamp < updated_at) continue; // 时间戳太旧\n\n const value = stringPool[poolIndex]!;\n productResult[field] = [value, timestamp];\n }\n\n result[product_id] = productResult;\n }\n\n return result;\n };\n\n // 导出内部统计信息用于调试\n const getStats = () => ({\n productCount: products.length,\n fieldCount: dataLength,\n stringPoolSize: stringPool.length,\n activeStrings: stringPool.length - freeIndices.length,\n freeIndices: freeIndices.length,\n memoryEstimate: {\n data: data.length * 8, // Float64Array 每个元素8字节\n pool: stringPool.reduce((sum, str) => sum + (str ? str.length * 2 : 0), 0),\n structures: products.length * 50 + stringPool.length * 16, // 粗略估计\n },\n });\n\n const filterValues = <K extends IQuoteKey>(\n product_ids: string[],\n fields: K[],\n ): Record<string, Record<K, string>> => {\n const result: Record<string, Record<K, string>> = {};\n for (const product_id of product_ids) {\n result[product_id] = {} as Record<K, string>;\n for (const field of fields) {\n const tuple = getValueTuple(product_id, field);\n result[product_id][field] = tuple ? tuple[0] : '';\n }\n }\n return result;\n };\n\n return { update, dumpAsObject, getValueTuple, filter, filterValues };\n};\n"]}
|