@yuants/app-virtual-exchange 0.18.5 → 0.18.7
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/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.map +1 -1
- package/lib/credential.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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { }
|
package/dist/credential.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAW,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAO9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC;AAEzF;;;;GAIG;AACH,MAAM,6BAA6B,GAAG,WAAW,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;IACvE,MAAM,GAAG,GAAG,qCAAqC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;IAC5E,MAAM,GAAG,GAAG,MAAM,UAAU,CAAY,QAAQ,EAAE,GAAG,CAAC,CAAC;IACvD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,QAAQ,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAwB,CAAC;IAC1F,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,EAAE,aAAqB,EAAE,EAAE;IACpE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAwB,CAAC;IACpE,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE;IACpC,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE;QAC1C,MAAM,EAAE,gBAAgB;QACxB,IAAI,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE;KACtC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxG,OAAO,OAAO,CAAC,GAAG,CAChB,CACE,MAAM,EACN,KAAK,EAML,EAAE;QACF,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE;
|
|
1
|
+
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, listSecrets, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst credentialReader = process.env.NODE_UNIT_PUBLIC_KEY || terminal.keyPair.public_key;\n\n/**\n * 根据 secret sign 解析出对应的 exchange credential\n * 此处可以做缓存,因为同一个 secret sign 对应的 credential 信息永远不会变化,可以节约解密和后续 SQL 查询的开销\n * 得到 credential 后,此 credential 不一定是有效的,因为可能凭证信息已经过期或被撤销\n */\nconst secretSignToCredentialIdCache = createCache(async (sign: string) => {\n const sql = `SELECT * FROM secret WHERE sign = ${escapeSQL(sign)} LIMIT 1;`;\n const res = await requestSQL<ISecret[]>(terminal, sql);\n if (res.length === 0) throw newError('SECRET_NOT_FOUND', { sign });\n const secret = res[0];\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n return credential;\n});\n\n/**\n * 根据 credential 信息解析出对应的 credential ID\n * 此处可以做缓存,因为同一个 credential 永远对应同一个 credential ID,可以节约后续 SQL 查询的开销\n * 但是需要注意的是,credential ID 可能会因为凭证被撤销而失效,但是可以在下游调用其他服务时感知到,因此可以永久缓存\n */\nconst credentialIdCache = createCache(async (credentialKey: string) => {\n const credential = JSON.parse(credentialKey) as IExchangeCredential;\n const res = await getCredentialId(terminal, credential);\n return res.data;\n});\n\nconst listAllCredentials = async () => {\n const secrets = await listSecrets(terminal, {\n reader: credentialReader,\n tags: { type: 'exchange_credential' },\n });\n\n const results = await Promise.allSettled(secrets.map((secret) => getCredentialBySecretId(secret.sign)));\n return results.map(\n (\n result,\n index,\n ): {\n sign: string;\n credential: IExchangeCredential | null;\n credentialId: string | null;\n error: any;\n } => {\n if (result.status === 'fulfilled') {\n return {\n sign: secrets[index].sign,\n credential: result.value.credential,\n credentialId: result.value.credentialId,\n error: null,\n };\n } else {\n return {\n sign: secrets[index].sign,\n credential: null,\n credentialId: null,\n error: `${result.reason}`,\n };\n }\n },\n );\n};\n\nterminal.server.provideService<IExchangeCredential, ISecret>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n const secret = await writeSecret(terminal, credentialReader, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK', data: secret } };\n },\n);\n\n// For Debugging Purpose\nterminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n});\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\nexport const validCredentials$ = defer(() => listAllCredentials()).pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n if (!x) return map;\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n repeat({ delay: 10000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const validCredentialTypes$ = validCredentials$.pipe(\n map((credentials) => {\n const types = new Set<string>();\n credentials.forEach((credential) => {\n types.add(credential.type);\n });\n return Array.from(types);\n }),\n);\n\n/**\n * 根据 secret sign 解析出对应的 credential 以及 credential ID\n * @param sign - secret sign\n * @returns 解析得到的 credential 以及对应的 credential ID\n * @throws 如果无法解析出对应的 credential 或 credential ID,则抛出异常\n *\n * 不依赖 List Credential 服务,可以及时感知凭证的新增和变更\n */\nexport const getCredentialBySecretId = async (sign: string) => {\n const credential = await secretSignToCredentialIdCache.query(sign);\n if (!credential) throw newError('CREDENTIAL_NOT_RESOLVED', { sign });\n const credentialId = await credentialIdCache.query(JSON.stringify(credential));\n if (!credentialId) throw newError('CREDENTIAL_ID_NOT_RESOLVED', { sign });\n return { sign, credential, credentialId };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-services.js","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAU,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,iBAAiB;KACd,IAAI,CACH,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EACnC,SAAS,CACP,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EACZ,CAAC,CAAC,aAAa,EAAE,UAAU,CAAC,EAAE,EAAE,CAC9B,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE;IACrB,OAAO,CAAC,IAAI,CAAC,2CAA2C,aAAa,EAAE,CAAC,CAAC;IACzE,4BAA4B;IAC5B;
|
|
1
|
+
{"version":3,"file":"legacy-services.js","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { provideAccountInfoService } from '@yuants/data-account';\nimport { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { listWatch, newError } from '@yuants/utils';\nimport { map, Observable } from 'rxjs';\nimport { validCredentials$ } from './credential';\nimport { polyfillOrders, polyfillPosition } from './position';\n\nconst terminal = Terminal.fromNodeEnv();\n\nvalidCredentials$\n .pipe(\n map((x) => Array.from(x.entries())),\n listWatch(\n ([id]) => id,\n ([credential_id, credential]) =>\n new Observable((sub) => {\n console.info(`Setting up VEX services for credential: ${credential_id}`);\n // Setup AccountInfo Service\n {\n const service = provideAccountInfoService(\n terminal,\n credential_id,\n async () => {\n const res = await getPositions(terminal, credential);\n if (!res.data) throw newError('FETCH_POSITIONS_FAILED', { credential_id, res });\n const polyfilledPositions = await polyfillPosition(res.data);\n polyfilledPositions.forEach((pos) => {\n pos.account_id = credential_id;\n });\n return polyfilledPositions;\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup Pending Orders Service\n {\n const service = providePendingOrdersService(\n terminal,\n credential_id,\n async () => {\n const res = await getOrders(terminal, credential);\n if (!res.data) throw newError('FETCH_ORDERS_FAILED', { credential_id, res });\n\n res.data.forEach((order) => {\n order.account_id = credential_id;\n });\n\n await polyfillOrders(res.data);\n\n return res.data;\n },\n {\n auto_refresh_interval: 10000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup SubmitOrder Service\n {\n const service = terminal.server.provideService<IOrder, { order_id: string }>(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await submitOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup ModifyOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await modifyOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup CancelOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const [order] = await polyfillOrders([msg.req]);\n const res = await cancelOrder(terminal, credential, order);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n }),\n ),\n )\n .subscribe();\n"]}
|
package/dist/position.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { createClientProductCache } from '@yuants/data-product';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\nconst productCache = createClientProductCache(terminal);\nconst quoteCache = createCache<IQuote>(\n async (product_id) => {\n const sql = `select * from quote where product_id = ${escapeSQL(product_id)}`;\n const [quote] = await requestSQL<IQuote[]>(terminal, sql);\n return quote;\n },\n { expire: 30_000 },\n);\n\nconst interestRateIntervalCache = createCache(\n async (product_id: string) => {\n const sql = `select created_at from interest_rate where series_id = ${escapeSQL(\n product_id,\n )} order by created_at desc limit 2`;\n const rates = await requestSQL<{ created_at: string }[]>(terminal, sql);\n if (rates.length < 2) return undefined;\n const prev = new Date(rates[0].created_at).getTime();\n const prevOfPrev = new Date(rates[1].created_at).getTime();\n const interval = prev - prevOfPrev;\n return {\n prev,\n prevOfPrev,\n interval,\n };\n },\n { swrAfter: 60_000, expire: 3600_000 },\n);\n\nexport const polyfillPosition = async (positions: IPosition[]): Promise<IPosition[]> => {\n // TODO: 使用 batch query SQL 优化 product / quote 查询性能\n for (const pos of positions) {\n const [theProduct, quote, interestRateInterval] = await Promise.all([\n productCache.query(pos.product_id),\n quoteCache.query(pos.product_id),\n interestRateIntervalCache.query(pos.product_id),\n ]);\n\n // 估值 = value_scale * volume * closable_price\n if (theProduct) {\n if (theProduct.base_currency) {\n pos.base_currency = theProduct.base_currency;\n }\n if (theProduct.quote_currency) {\n pos.quote_currency = theProduct.quote_currency;\n }\n if (pos.size === undefined && pos.volume !== undefined && pos.direction !== undefined) {\n pos.size = (pos.direction === 'LONG' ? 1 : -1) * pos.volume * (theProduct.value_scale || 1) + '';\n }\n if (pos.free_size === undefined && pos.free_volume !== undefined && pos.direction !== undefined) {\n pos.free_size =\n (pos.direction === 'LONG' ? 1 : -1) * pos.free_volume * (theProduct.value_scale || 1) + '';\n }\n pos.valuation = Math.abs((theProduct.value_scale || 1) * pos.volume * pos.closable_price);\n }\n\n if (quote && pos.size) {\n const sizeNum = +pos.size;\n if (pos.current_price === undefined) {\n if (sizeNum > 0) {\n // 多头头寸使用买一价作为可平仓价格,如果没有买一价则使用最新价\n pos.current_price = (quote.ask_price || quote.last_price) + '';\n } else {\n // 空头头寸使用卖一价作为可平仓价格,如果没有卖一价则使用最新价\n pos.current_price = (quote.bid_price || quote.last_price) + '';\n }\n }\n\n // 计算名义价值\n if (pos.notional === undefined) {\n pos.notional = sizeNum * (+pos.current_price || 0) + '';\n }\n }\n\n // 利率相关信息的追加\n if (quote) {\n // 优先使用 quote 表中的结算间隔\n if (quote.interest_rate_settlement_interval) {\n pos.settlement_interval = +quote.interest_rate_settlement_interval;\n }\n if (quote.interest_rate_next_settled_at !== null) {\n const nextSettledAt = new Date(quote.interest_rate_next_settled_at).getTime();\n // 优先使用行情数据中的下一个结算时间\n pos.settlement_scheduled_at = nextSettledAt;\n\n // 如果还没有结算周期,使用下一个结算时间推算结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval !== undefined) {\n const interval = nextSettledAt - interestRateInterval.prev;\n pos.settlement_interval = interval;\n }\n } else if (quote.interest_rate_next_settled_at === null && interestRateInterval !== undefined) {\n // 估算下一个结算时间\n // 找到 prev + k * interval > now 的最小 k,则下一个结算时间为 prev + k * interval\n const k = Math.ceil((Date.now() - interestRateInterval.prev) / interestRateInterval.interval);\n pos.settlement_scheduled_at = interestRateInterval.prev + k * interestRateInterval.interval;\n }\n\n // 如果还没有结算间隔,则使用 interest rate 表的时间间隔作为结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval) {\n pos.settlement_interval = interestRateInterval.interval;\n }\n\n if (pos.direction === 'LONG') {\n if (quote.interest_rate_long !== null) {\n pos.interest_to_settle = +quote.interest_rate_long * pos.valuation;\n }\n }\n if (pos.direction === 'SHORT') {\n if (quote.interest_rate_short !== null) {\n pos.interest_to_settle = +quote.interest_rate_short * pos.valuation;\n }\n }\n }\n }\n return positions;\n};\n\nexport const polyfillOrders = async (orders: IOrder[]): Promise<IOrder[]> => {\n for (const order of orders) {\n const theProduct = await productCache.query(order.product_id);\n if (theProduct) {\n if (order.size !== undefined) {\n const sizeNum = +order.size;\n const sizeStep = theProduct.volume_step * theProduct.value_scale;\n if (!(sizeStep > 0)) throw newError('INVALID_SIZE_STEP', { product: theProduct, sizeStep });\n // check size is multiple of sizeStep\n if (Math.abs(sizeNum - Math.round(sizeNum / sizeStep) * sizeStep) > 1e-16) {\n throw newError('INVALID_ORDER_SIZE_NOT_MULTIPLE_OF_SIZE_STEP', {\n order,\n sizeStep,\n sizeNum,\n product: theProduct,\n });\n }\n\n if (sizeNum >= 0) {\n order.order_direction = order.is_close ? 'CLOSE_SHORT' : 'OPEN_LONG';\n } else {\n order.order_direction = order.is_close ? 'CLOSE_LONG' : 'OPEN_SHORT';\n }\n order.volume = Math.abs(sizeNum) / theProduct.value_scale;\n }\n }\n }\n return orders;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { createClientProductCache } from '@yuants/data-product';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\n\nconst terminal = Terminal.fromNodeEnv();\nconst productCache = createClientProductCache(terminal);\nconst quoteCache = createCache<IQuote>(\n async (product_id) => {\n const sql = `select * from quote where product_id = ${escapeSQL(product_id)}`;\n const [quote] = await requestSQL<IQuote[]>(terminal, sql);\n return quote;\n },\n { expire: 30_000 },\n);\n\nconst interestRateIntervalCache = createCache(\n async (product_id: string) => {\n const sql = `select created_at from interest_rate where series_id = ${escapeSQL(\n product_id,\n )} order by created_at desc limit 2`;\n const rates = await requestSQL<{ created_at: string }[]>(terminal, sql);\n if (rates.length < 2) return undefined;\n const prev = new Date(rates[0].created_at).getTime();\n const prevOfPrev = new Date(rates[1].created_at).getTime();\n const interval = prev - prevOfPrev;\n return {\n prev,\n prevOfPrev,\n interval,\n };\n },\n { swrAfter: 60_000, expire: 3600_000 },\n);\n\nexport const polyfillPosition = async (positions: IPosition[]): Promise<IPosition[]> => {\n // TODO: 使用 batch query SQL 优化 product / quote 查询性能\n for (const pos of positions) {\n const [theProduct, quote, interestRateInterval] = await Promise.all([\n productCache.query(pos.product_id),\n quoteCache.query(pos.product_id),\n interestRateIntervalCache.query(pos.product_id),\n ]);\n\n // 估值 = value_scale * volume * closable_price\n if (theProduct) {\n if (theProduct.base_currency) {\n pos.base_currency = theProduct.base_currency;\n }\n if (theProduct.quote_currency) {\n pos.quote_currency = theProduct.quote_currency;\n }\n if (pos.size === undefined && pos.volume !== undefined && pos.direction !== undefined) {\n pos.size = (pos.direction === 'LONG' ? 1 : -1) * pos.volume * (theProduct.value_scale || 1) + '';\n }\n if (pos.free_size === undefined && pos.free_volume !== undefined && pos.direction !== undefined) {\n pos.free_size =\n (pos.direction === 'LONG' ? 1 : -1) * pos.free_volume * (theProduct.value_scale || 1) + '';\n }\n pos.valuation = Math.abs((theProduct.value_scale || 1) * pos.volume * pos.closable_price);\n }\n\n if (quote && pos.size) {\n const sizeNum = +pos.size;\n if (pos.current_price === undefined) {\n if (sizeNum > 0) {\n // 多头头寸使用买一价作为可平仓价格,如果没有买一价则使用最新价\n pos.current_price = (quote.ask_price || quote.last_price) + '';\n } else {\n // 空头头寸使用卖一价作为可平仓价格,如果没有卖一价则使用最新价\n pos.current_price = (quote.bid_price || quote.last_price) + '';\n }\n }\n\n // 计算名义价值\n if (pos.notional === undefined) {\n pos.notional = sizeNum * (+pos.current_price || 0) + '';\n }\n }\n\n // 利率相关信息的追加\n if (quote) {\n // 优先使用 quote 表中的结算间隔\n if (quote.interest_rate_settlement_interval) {\n pos.settlement_interval = +quote.interest_rate_settlement_interval;\n }\n if (quote.interest_rate_next_settled_at !== null) {\n const nextSettledAt = new Date(quote.interest_rate_next_settled_at).getTime();\n // 优先使用行情数据中的下一个结算时间\n pos.settlement_scheduled_at = nextSettledAt;\n\n // 如果还没有结算周期,使用下一个结算时间推算结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval !== undefined) {\n const interval = nextSettledAt - interestRateInterval.prev;\n pos.settlement_interval = interval;\n }\n } else if (quote.interest_rate_next_settled_at === null && interestRateInterval !== undefined) {\n // 估算下一个结算时间\n // 找到 prev + k * interval > now 的最小 k,则下一个结算时间为 prev + k * interval\n const k = Math.ceil((Date.now() - interestRateInterval.prev) / interestRateInterval.interval);\n pos.settlement_scheduled_at = interestRateInterval.prev + k * interestRateInterval.interval;\n }\n\n // 如果还没有结算间隔,则使用 interest rate 表的时间间隔作为结算间隔\n if (pos.settlement_interval === undefined && interestRateInterval) {\n pos.settlement_interval = interestRateInterval.interval;\n }\n\n if (pos.direction === 'LONG') {\n if (quote.interest_rate_long !== null) {\n pos.interest_to_settle = +quote.interest_rate_long * pos.valuation;\n }\n }\n if (pos.direction === 'SHORT') {\n if (quote.interest_rate_short !== null) {\n pos.interest_to_settle = +quote.interest_rate_short * pos.valuation;\n }\n }\n }\n }\n return positions;\n};\n\nexport const polyfillOrders = async (orders: IOrder[]): Promise<IOrder[]> => {\n for (const order of orders) {\n const theProduct = await productCache.query(order.product_id);\n if (theProduct) {\n if (order.size !== undefined) {\n const sizeNum = +order.size;\n const sizeStep = theProduct.volume_step * theProduct.value_scale;\n if (!(sizeStep > 0)) throw newError('INVALID_SIZE_STEP', { product: theProduct, sizeStep });\n // check size is multiple of sizeStep\n if (Math.abs(sizeNum - Math.round(sizeNum / sizeStep) * sizeStep) > 1e-16) {\n throw newError('INVALID_ORDER_SIZE_NOT_MULTIPLE_OF_SIZE_STEP', {\n order,\n sizeStep,\n sizeNum,\n product: theProduct,\n });\n }\n\n if (sizeNum >= 0) {\n order.order_direction = order.is_close ? 'CLOSE_SHORT' : 'OPEN_LONG';\n } else {\n order.order_direction = order.is_close ? 'CLOSE_LONG' : 'OPEN_SHORT';\n }\n order.volume = Math.abs(sizeNum) / theProduct.value_scale;\n }\n }\n }\n return orders;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implementations.test.js","sourceRoot":"","sources":["../../../src/quote/__tests__/implementations.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { implementations } from '../implementations';\nimport { IQuoteKey, IQuoteUpdateAction } from '../types';\n\n// 测试所有实现的通用测试套件\ndescribe('IQuoteState implementations', () => {\n // 测试每个实现\n Object.entries(implementations).forEach(([name, createQuoteState]) => {\n describe(`${name} implementation`, () => {\n let quoteState: ReturnType<typeof createQuoteState>;\n\n beforeEach(() => {\n quoteState = createQuoteState();\n });\n\n // 测试 1: 初始状态应该是空的\n it('should have empty initial state', () => {\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual({});\n });\n\n // 测试 2: 更新单个产品的单个字段\n it('should update single field for single product', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证通过 getValueTuple 获取\n const tuple = quoteState.getValueTuple('product_001', 'last_price');\n expect(tuple).toEqual(['100.5', 1000]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 3: 更新多个产品和多个字段\n it('should update multiple fields for multiple products', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n ask_price: ['101.0', 1001],\n },\n product_002: {\n bid_price: ['99.0', 1002],\n ask_volume: ['500', 1003],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证所有字段\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['100.5', 1000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n expect(quoteState.getValueTuple('product_002', 'bid_price')).toEqual(['99.0', 1002]);\n expect(quoteState.getValueTuple('product_002', 'ask_volume')).toEqual(['500', 1003]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 4: 更新应该覆盖旧的时间戳,但忽略更旧的时间戳\n it('should overwrite with newer timestamp, ignore older timestamp', () => {\n // 初始更新\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n // 用更新的时间戳覆盖\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n\n // 用更旧的时间戳尝试覆盖(应该被忽略)\n quoteState.update({\n product_001: {\n last_price: ['300.0', 1500], // 时间戳 1500 比 2000 旧\n },\n });\n\n // 应该仍然是旧的值\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n });\n\n // 测试 5: 获取不存在的产品或字段应该返回 undefined\n it('should return undefined for non-existent product or field', () => {\n expect(quoteState.getValueTuple('non_existent', 'last_price')).toBeUndefined();\n\n // 添加一个产品但不包含该字段\n quoteState.update({\n product_001: {\n ask_price: ['101.0', 1000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toBeUndefined();\n expect(quoteState.getValueTuple('product_002', 'last_price')).toBeUndefined();\n });\n\n // 测试 6: filter 方法应该返回符合条件的数据\n it('should filter data by product_ids, fields, and updated_at', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000], // 较新的时间戳\n bid_price: ['99.0', 500], // 较旧的时间戳\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n product_003: {\n last_price: ['300.0', 1200],\n },\n });\n\n // 测试 1: 过滤特定产品和字段,时间阈值 1000\n const result1 = quoteState.filter(['product_001', 'product_002'], ['last_price', 'ask_price'], 1000);\n\n expect(result1).toEqual({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n });\n\n // 测试 2: 过滤时间阈值 1500(排除较旧的数据)\n const result2 = quoteState.filter(\n ['product_001', 'product_002', 'product_003'],\n ['last_price', 'bid_price'],\n 1500,\n );\n\n expect(result2).toEqual({\n product_001: {\n // last_price 时间戳 1000 < 1500,应该被排除\n // bid_price 时间戳 500 < 1500,应该被排除\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n product_003: {\n // last_price 时间戳 1200 < 1500,应该被排除\n },\n });\n\n // 测试 3: 过滤不存在的产品应该返回空对象\n const result3 = quoteState.filter(['non_existent'], ['last_price'], 0);\n\n expect(result3).toEqual({\n non_existent: {},\n });\n });\n\n // 测试 7: 空更新不应该改变状态\n it('should handle empty update action', () => {\n // 先添加一些数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n const beforeDump = quoteState.dumpAsObject();\n\n // 空更新\n quoteState.update({});\n\n const afterDump = quoteState.dumpAsObject();\n expect(afterDump).toEqual(beforeDump);\n });\n\n // 测试 8: 更新时只提供部分字段,不应影响其他字段\n it('should not affect other fields when updating partial fields', () => {\n // 初始设置两个字段\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 1001],\n },\n });\n\n // 只更新一个字段\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n // last_price 应该更新,ask_price 应该保持不变\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n });\n\n // 测试 9: 重复的更新应该保持幂等性\n it('should be idempotent for duplicate updates', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.0', 1000],\n },\n };\n\n // 多次执行相同的更新\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n\n // 状态应该与单次更新相同\n expect(quoteState.dumpAsObject()).toEqual(updateAction);\n });\n\n // 测试 10: 字段名称应该是 IQuoteKey 类型\n it('should handle all IQuoteKey field types', () => {\n const allFields: IQuoteKey[] = [\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 const updateAction: IQuoteUpdateAction = {\n product_001: {},\n };\n\n // 为每个字段设置值\n allFields.forEach((field, index) => {\n updateAction['product_001'][field] = [`value_${index}`, 1000 + index];\n });\n\n quoteState.update(updateAction);\n\n // 验证每个字段\n allFields.forEach((field, index) => {\n expect(quoteState.getValueTuple('product_001', field)).toEqual([`value_${index}`, 1000 + index]);\n });\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 11: filterValues 方法应该返回值(即使字段不存在)\n it('should return values via filterValues (even if field missing)', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n // bid_price not set\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n });\n\n // 测试 1: 获取存在的字段\n const result1 = quoteState.filterValues(['product_001', 'product_002'], ['last_price', 'ask_price']);\n expect(result1).toEqual({\n product_001: {\n last_price: '100.0',\n ask_price: '101.0',\n },\n product_002: {\n last_price: '200.0',\n ask_price: '',\n },\n });\n\n // 测试 2: 获取不存在的产品和字段\n const result2 = quoteState.filterValues(['product_001', 'non_existent'], ['last_price', 'bid_price']);\n expect(result2).toEqual({\n product_001: {\n last_price: '100.0',\n bid_price: '',\n },\n non_existent: {\n last_price: '',\n bid_price: '',\n },\n });\n\n // 测试 3: 空产品列表\n const result3 = quoteState.filterValues([], ['last_price']);\n expect(result3).toEqual({});\n\n // 测试 4: 空字段列表\n const result4 = quoteState.filterValues(['product_001'], []);\n expect(result4).toEqual({\n product_001: {},\n });\n\n // 测试 5: 所有字段类型\n const allFields: IQuoteKey[] = [\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 const result5 = quoteState.filterValues(['product_001'], allFields);\n expect(Object.keys(result5.product_001)).toEqual(allFields);\n expect(result5.product_001.last_price).toBe('100.0');\n expect(result5.product_001.ask_price).toBe('101.0');\n // 其他字段应为空字符串\n expect(result5.product_001.bid_price).toBe('');\n expect(result5.product_001.ask_volume).toBe('');\n });\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"implementations.test.js","sourceRoot":"","sources":["../../../src/quote/__tests__/implementations.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { implementations } from '../implementations';\nimport { IQuoteKey, IQuoteUpdateAction } from '../types';\n\n// 测试所有实现的通用测试套件\ndescribe('IQuoteState implementations', () => {\n // 测试每个实现\n Object.entries(implementations).forEach(([name, createQuoteState]) => {\n describe(`${name} implementation`, () => {\n let quoteState: ReturnType<typeof createQuoteState>;\n\n beforeEach(() => {\n quoteState = createQuoteState();\n });\n\n // 测试 1: 初始状态应该是空的\n it('should have empty initial state', () => {\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual({});\n });\n\n // 测试 2: 更新单个产品的单个字段\n it('should update single field for single product', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证通过 getValueTuple 获取\n const tuple = quoteState.getValueTuple('product_001', 'last_price');\n expect(tuple).toEqual(['100.5', 1000]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 3: 更新多个产品和多个字段\n it('should update multiple fields for multiple products', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.5', 1000],\n ask_price: ['101.0', 1001],\n },\n product_002: {\n bid_price: ['99.0', 1002],\n ask_volume: ['500', 1003],\n },\n };\n\n quoteState.update(updateAction);\n\n // 验证所有字段\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['100.5', 1000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n expect(quoteState.getValueTuple('product_002', 'bid_price')).toEqual(['99.0', 1002]);\n expect(quoteState.getValueTuple('product_002', 'ask_volume')).toEqual(['500', 1003]);\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 4: 更新应该覆盖旧的时间戳,但忽略更旧的时间戳\n it('should overwrite with newer timestamp, ignore older timestamp', () => {\n // 初始更新\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n // 用更新的时间戳覆盖\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n\n // 用更旧的时间戳尝试覆盖(应该被忽略)\n quoteState.update({\n product_001: {\n last_price: ['300.0', 1500], // 时间戳 1500 比 2000 旧\n },\n });\n\n // 应该仍然是旧的值\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n });\n\n // 测试 5: 获取不存在的产品或字段应该返回 undefined\n it('should return undefined for non-existent product or field', () => {\n expect(quoteState.getValueTuple('non_existent', 'last_price')).toBeUndefined();\n\n // 添加一个产品但不包含该字段\n quoteState.update({\n product_001: {\n ask_price: ['101.0', 1000],\n },\n });\n\n expect(quoteState.getValueTuple('product_001', 'last_price')).toBeUndefined();\n expect(quoteState.getValueTuple('product_002', 'last_price')).toBeUndefined();\n });\n\n // 测试 6: filter 方法应该返回符合条件的数据\n it('should filter data by product_ids, fields, and updated_at', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000], // 较新的时间戳\n bid_price: ['99.0', 500], // 较旧的时间戳\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n product_003: {\n last_price: ['300.0', 1200],\n },\n });\n\n // 测试 1: 过滤特定产品和字段,时间阈值 1000\n const result1 = quoteState.filter(['product_001', 'product_002'], ['last_price', 'ask_price'], 1000);\n\n expect(result1).toEqual({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n },\n product_002: {\n last_price: ['200.0', 1500],\n ask_price: ['201.0', 2500],\n },\n });\n\n // 测试 2: 过滤时间阈值 1500(排除较旧的数据)\n const result2 = quoteState.filter(\n ['product_001', 'product_002', 'product_003'],\n ['last_price', 'bid_price'],\n 1500,\n );\n\n expect(result2).toEqual({\n product_001: {\n // last_price 时间戳 1000 < 1500,应该被排除\n // bid_price 时间戳 500 < 1500,应该被排除\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n product_003: {\n // last_price 时间戳 1200 < 1500,应该被排除\n },\n });\n\n // 测试 3: 过滤不存在的产品应该返回空对象\n const result3 = quoteState.filter(['non_existent'], ['last_price'], 0);\n\n expect(result3).toEqual({\n non_existent: {},\n });\n });\n\n // 测试 7: 空更新不应该改变状态\n it('should handle empty update action', () => {\n // 先添加一些数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n },\n });\n\n const beforeDump = quoteState.dumpAsObject();\n\n // 空更新\n quoteState.update({});\n\n const afterDump = quoteState.dumpAsObject();\n expect(afterDump).toEqual(beforeDump);\n });\n\n // 测试 8: 更新时只提供部分字段,不应影响其他字段\n it('should not affect other fields when updating partial fields', () => {\n // 初始设置两个字段\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 1001],\n },\n });\n\n // 只更新一个字段\n quoteState.update({\n product_001: {\n last_price: ['200.0', 2000],\n },\n });\n\n // last_price 应该更新,ask_price 应该保持不变\n expect(quoteState.getValueTuple('product_001', 'last_price')).toEqual(['200.0', 2000]);\n expect(quoteState.getValueTuple('product_001', 'ask_price')).toEqual(['101.0', 1001]);\n });\n\n // 测试 9: 重复的更新应该保持幂等性\n it('should be idempotent for duplicate updates', () => {\n const updateAction: IQuoteUpdateAction = {\n product_001: {\n last_price: ['100.0', 1000],\n },\n };\n\n // 多次执行相同的更新\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n quoteState.update(updateAction);\n\n // 状态应该与单次更新相同\n expect(quoteState.dumpAsObject()).toEqual(updateAction);\n });\n\n // 测试 10: 字段名称应该是 IQuoteKey 类型\n it('should handle all IQuoteKey field types', () => {\n const allFields: IQuoteKey[] = [\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 const updateAction: IQuoteUpdateAction = {\n product_001: {},\n };\n\n // 为每个字段设置值\n allFields.forEach((field, index) => {\n updateAction['product_001'][field] = [`value_${index}`, 1000 + index];\n });\n\n quoteState.update(updateAction);\n\n // 验证每个字段\n allFields.forEach((field, index) => {\n expect(quoteState.getValueTuple('product_001', field)).toEqual([`value_${index}`, 1000 + index]);\n });\n\n // 验证 dumpAsObject\n const dumped = quoteState.dumpAsObject();\n expect(dumped).toEqual(updateAction);\n });\n\n // 测试 11: filterValues 方法应该返回值(即使字段不存在)\n it('should return values via filterValues (even if field missing)', () => {\n // 设置测试数据\n quoteState.update({\n product_001: {\n last_price: ['100.0', 1000],\n ask_price: ['101.0', 2000],\n // bid_price not set\n },\n product_002: {\n last_price: ['200.0', 1500],\n },\n });\n\n // 测试 1: 获取存在的字段\n const result1 = quoteState.filterValues(['product_001', 'product_002'], ['last_price', 'ask_price']);\n expect(result1).toEqual({\n product_001: {\n last_price: '100.0',\n ask_price: '101.0',\n },\n product_002: {\n last_price: '200.0',\n ask_price: '',\n },\n });\n\n // 测试 2: 获取不存在的产品和字段\n const result2 = quoteState.filterValues(['product_001', 'non_existent'], ['last_price', 'bid_price']);\n expect(result2).toEqual({\n product_001: {\n last_price: '100.0',\n bid_price: '',\n },\n non_existent: {\n last_price: '',\n bid_price: '',\n },\n });\n\n // 测试 3: 空产品列表\n const result3 = quoteState.filterValues([], ['last_price']);\n expect(result3).toEqual({});\n\n // 测试 4: 空字段列表\n const result4 = quoteState.filterValues(['product_001'], []);\n expect(result4).toEqual({\n product_001: {},\n });\n\n // 测试 5: 所有字段类型\n const allFields: IQuoteKey[] = [\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 const result5 = quoteState.filterValues(['product_001'], allFields);\n expect(Object.keys(result5.product_001)).toEqual(allFields);\n expect(result5.product_001.last_price).toBe('100.0');\n expect(result5.product_001.ask_price).toBe('101.0');\n // 其他字段应为空字符串\n expect(result5.product_001.bid_price).toBe('');\n expect(result5.product_001.ask_volume).toBe('');\n });\n });\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForkedQuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/ForkedQuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { QuoteStateComparisonTest } from './QuoteStateComparisonTest';\nimport { PerformanceTester } from './PerformanceTester';\n\nconst execAsync = promisify(exec);\n\n/**\n * 使用子进程进行隔离内存测试的对比测试类\n * 每个实现都在独立的子进程中运行,确保内存测试的公平性\n */\nexport class ForkedQuoteStateComparisonTest {\n private nameA: string;\n private nameB: string;\n private workerScriptPath: string;\n\n constructor(\n nameA: string = 'Current',\n nameB: string = 'Baseline',\n workerScriptPath: string = __dirname + '/worker.ts',\n ) {\n this.nameA = nameA;\n this.nameB = nameB;\n this.workerScriptPath = workerScriptPath;\n }\n\n /**\n * 运行单个测试场景的子进程\n */\n private async runWorkerTest(\n implName: string,\n testType: string,\n productCount: number,\n extraArgs: Record<string, string> = {},\n ): Promise<any> {\n // 构建命令行参数\n const args = [`--impl=${implName}`, `--test=${testType}`, `--product-count=${productCount}`];\n\n // 添加额外参数\n for (const [key, value] of Object.entries(extraArgs)) {\n args.push(`--${key}=${value}`);\n }\n\n // 执行 worker 脚本,启用 GC 以进行公平的内存测试\n const command = `node --expose-gc $(which ts-node) ${this.workerScriptPath} ${args.join(' ')}`;\n\n try {\n const { stdout, stderr } = await execAsync(command);\n\n if (stderr && stderr.trim()) {\n console.error(`Worker stderr (${implName}, ${testType}, ${productCount}):`, stderr);\n }\n\n const result = JSON.parse(stdout.trim());\n\n if (!result.success) {\n // 子进程返回了失败结果\n return {\n success: false,\n error: result.error || 'Unknown error',\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n\n return result;\n } catch (error) {\n // 子进程执行失败(如 OOM killed、命令不存在等)\n console.error(`Worker execution failed (${implName}, ${testType}, ${productCount}):`, error);\n\n // 返回一个失败对象,而不是抛出错误\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n }\n\n /**\n * 运行初始化测试对比\n */\n async runInitializationTestComparison(\n productCount: number,\n iterations: number = 3,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行初始化对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'init', productCount, {\n iterations: iterations.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'init', productCount, {\n iterations: iterations.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行更新测试对比\n */\n async runUpdateTestComparison(\n productCount: number,\n updateCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行更新对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${updateCount} 更新)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行查询测试对比\n */\n async runQueryTestComparison(\n productCount: number,\n queryCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行查询对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${queryCount} 查询)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行过滤测试对比\n */\n async runFilterTestComparison(\n productCount: number,\n filterCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行过滤对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${filterCount} 过滤)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行转储测试对比\n */\n async runDumpTestComparison(productCount: number): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行转储对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'dump', productCount);\n const resultB = await this.runWorkerTest('baseline', 'dump', productCount);\n\n return { resultA, resultB };\n }\n\n /**\n * 打印对比结果(复用现有的对比结果打印逻辑)\n */\n private printComparisonResults(resultsA: any[], resultsB: any[], testType: string): void {\n // 创建一个临时的 QuoteStateComparisonTest 实例来复用其打印逻辑\n const tempComparison = new QuoteStateComparisonTest(\n () => {\n throw new Error('Not implemented');\n },\n () => {\n throw new Error('Not implemented');\n },\n this.nameA,\n this.nameB,\n );\n\n // 使用私有方法,需要类型断言来访问\n const privateMethod = (tempComparison as any).printComparisonResults;\n if (typeof privateMethod === 'function') {\n privateMethod.call(tempComparison, resultsA, resultsB, testType);\n } else {\n // 如果无法访问私有方法,使用简化版本\n console.log(`\\n${this.nameA} vs ${this.nameB} - ${testType} 对比结果:`);\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const a = resultsA[i];\n const b = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = a.success === false;\n const isBFailed = b.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${a.productCount || b.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${a.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${a.avgTime || a.time}ms`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${b.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${b.avgTime || b.time}ms`);\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && 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 console.log('-'.repeat(80));\n continue;\n }\n\n console.log(`产品数量 ${a.productCount}: ${a.avgTime || a.time}ms vs ${b.avgTime || b.time}ms`);\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && 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 */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始子进程隔离内存对比测试: ${this.nameA} vs ${this.nameB}`);\n console.log('注意:每个测试都在独立的子进程中运行,确保内存测试的公平性');\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 const { resultA, resultB } = await this.runInitializationTestComparison(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, resultB } = await this.runUpdateTestComparison(\n scenario.productCount,\n scenario.updateIterations,\n );\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, resultB } = await this.runQueryTestComparison(\n scenario.productCount,\n scenario.queryIterations,\n );\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, resultB } = await this.runFilterTestComparison(\n scenario.productCount,\n scenario.filterIterations,\n );\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, resultB } = await this.runDumpTestComparison(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 const { resultA, resultB } = await this.runInitializationTestComparison(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":"ForkedQuoteStateComparisonTest.js","sourceRoot":"","sources":["../../../src/quote/benchmark/ForkedQuoteStateComparisonTest.ts"],"names":[],"mappings":"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","sourcesContent":["import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { QuoteStateComparisonTest } from './QuoteStateComparisonTest';\nimport { PerformanceTester } from './PerformanceTester';\n\nconst execAsync = promisify(exec);\n\n/**\n * 使用子进程进行隔离内存测试的对比测试类\n * 每个实现都在独立的子进程中运行,确保内存测试的公平性\n */\nexport class ForkedQuoteStateComparisonTest {\n private nameA: string;\n private nameB: string;\n private workerScriptPath: string;\n\n constructor(\n nameA: string = 'Current',\n nameB: string = 'Baseline',\n workerScriptPath: string = __dirname + '/worker.ts',\n ) {\n this.nameA = nameA;\n this.nameB = nameB;\n this.workerScriptPath = workerScriptPath;\n }\n\n /**\n * 运行单个测试场景的子进程\n */\n private async runWorkerTest(\n implName: string,\n testType: string,\n productCount: number,\n extraArgs: Record<string, string> = {},\n ): Promise<any> {\n // 构建命令行参数\n const args = [`--impl=${implName}`, `--test=${testType}`, `--product-count=${productCount}`];\n\n // 添加额外参数\n for (const [key, value] of Object.entries(extraArgs)) {\n args.push(`--${key}=${value}`);\n }\n\n // 执行 worker 脚本,启用 GC 以进行公平的内存测试\n const command = `node --expose-gc $(which ts-node) ${this.workerScriptPath} ${args.join(' ')}`;\n\n try {\n const { stdout, stderr } = await execAsync(command);\n\n if (stderr && stderr.trim()) {\n console.error(`Worker stderr (${implName}, ${testType}, ${productCount}):`, stderr);\n }\n\n const result = JSON.parse(stdout.trim());\n\n if (!result.success) {\n // 子进程返回了失败结果\n return {\n success: false,\n error: result.error || 'Unknown error',\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n\n return result;\n } catch (error) {\n // 子进程执行失败(如 OOM killed、命令不存在等)\n console.error(`Worker execution failed (${implName}, ${testType}, ${productCount}):`, error);\n\n // 返回一个失败对象,而不是抛出错误\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n impl: implName,\n test: testType,\n productCount,\n avgTime: null,\n time: null,\n heapUsedDiff: null,\n };\n }\n }\n\n /**\n * 运行初始化测试对比\n */\n async runInitializationTestComparison(\n productCount: number,\n iterations: number = 3,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行初始化对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'init', productCount, {\n iterations: iterations.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'init', productCount, {\n iterations: iterations.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行更新测试对比\n */\n async runUpdateTestComparison(\n productCount: number,\n updateCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行更新对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${updateCount} 更新)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'update', productCount, {\n 'update-count': updateCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行查询测试对比\n */\n async runQueryTestComparison(\n productCount: number,\n queryCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行查询对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${queryCount} 查询)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'query', productCount, {\n 'query-count': queryCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行过滤测试对比\n */\n async runFilterTestComparison(\n productCount: number,\n filterCount: number,\n ): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(\n `运行过滤对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品, ${filterCount} 过滤)`,\n );\n\n const resultA = await this.runWorkerTest('current', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n const resultB = await this.runWorkerTest('baseline', 'filter', productCount, {\n 'filter-count': filterCount.toString(),\n });\n\n return { resultA, resultB };\n }\n\n /**\n * 运行转储测试对比\n */\n async runDumpTestComparison(productCount: number): Promise<{\n resultA: any;\n resultB: any;\n }> {\n console.log(`运行转储对比测试: ${this.nameA} vs ${this.nameB} (${productCount} 产品)`);\n\n const resultA = await this.runWorkerTest('current', 'dump', productCount);\n const resultB = await this.runWorkerTest('baseline', 'dump', productCount);\n\n return { resultA, resultB };\n }\n\n /**\n * 打印对比结果(复用现有的对比结果打印逻辑)\n */\n private printComparisonResults(resultsA: any[], resultsB: any[], testType: string): void {\n // 创建一个临时的 QuoteStateComparisonTest 实例来复用其打印逻辑\n const tempComparison = new QuoteStateComparisonTest(\n () => {\n throw new Error('Not implemented');\n },\n () => {\n throw new Error('Not implemented');\n },\n this.nameA,\n this.nameB,\n );\n\n // 使用私有方法,需要类型断言来访问\n const privateMethod = (tempComparison as any).printComparisonResults;\n if (typeof privateMethod === 'function') {\n privateMethod.call(tempComparison, resultsA, resultsB, testType);\n } else {\n // 如果无法访问私有方法,使用简化版本\n console.log(`\\n${this.nameA} vs ${this.nameB} - ${testType} 对比结果:`);\n for (let i = 0; i < Math.min(resultsA.length, resultsB.length); i++) {\n const a = resultsA[i];\n const b = resultsB[i];\n\n // 检查是否有失败的测试\n const isAFailed = a.success === false;\n const isBFailed = b.success === false;\n\n if (isAFailed || isBFailed) {\n console.log(`\\n产品数量: ${a.productCount || b.productCount}`);\n\n if (isAFailed) {\n console.log(`❌ ${this.nameA} 测试失败: ${a.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameA}: ${a.avgTime || a.time}ms`);\n }\n\n if (isBFailed) {\n console.log(`❌ ${this.nameB} 测试失败: ${b.error || 'Unknown error'}`);\n } else {\n console.log(`${this.nameB}: ${b.avgTime || b.time}ms`);\n }\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && 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 console.log('-'.repeat(80));\n continue;\n }\n\n console.log(`产品数量 ${a.productCount}: ${a.avgTime || a.time}ms vs ${b.avgTime || b.time}ms`);\n\n // 打印内存使用(即使只有一个实现有数据)\n const memoryUsedA = a.heapUsedDiff;\n const memoryUsedB = b.heapUsedDiff;\n const hasMemoryA = memoryUsedA !== undefined && memoryUsedA !== null && !isNaN(memoryUsedA);\n const hasMemoryB = memoryUsedB !== undefined && 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 */\n async runComparisonTestSuite(): Promise<void> {\n console.log(`开始子进程隔离内存对比测试: ${this.nameA} vs ${this.nameB}`);\n console.log('注意:每个测试都在独立的子进程中运行,确保内存测试的公平性');\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 const { resultA, resultB } = await this.runInitializationTestComparison(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, resultB } = await this.runUpdateTestComparison(\n scenario.productCount,\n scenario.updateIterations,\n );\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, resultB } = await this.runQueryTestComparison(\n scenario.productCount,\n scenario.queryIterations,\n );\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, resultB } = await this.runFilterTestComparison(\n scenario.productCount,\n scenario.filterIterations,\n );\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, resultB } = await this.runDumpTestComparison(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 const { resultA, resultB } = await this.runInitializationTestComparison(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":"PerformanceTester.js","sourceRoot":"","sources":["../../../src/quote/benchmark/PerformanceTester.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,iBAAiB;IAC5B;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,WAAW,CAAI,EAAwB;QAClD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,KAAK,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAC/B,EAAwB,EACxB,aAAqB,CAAC;QAEtB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,WAA0B,CAAC;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"PerformanceTester.js","sourceRoot":"","sources":["../../../src/quote/benchmark/PerformanceTester.ts"],"names":[],"mappings":"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","sourcesContent":["import { performance } from 'perf_hooks';\n\n/**\n * 性能测试工具类\n */\nexport class PerformanceTester {\n /**\n * 测量函数执行时间\n */\n static async measureTime<T>(fn: () => Promise<T> | T): Promise<{ result: T; time: number }> {\n const start = performance.now();\n const result = await fn();\n const end = performance.now();\n return { result, time: end - start };\n }\n\n /**\n * 多次测量函数执行时间,取平均值\n */\n static async measureTimeWithStats<T>(\n fn: () => Promise<T> | T,\n iterations: number = 5,\n ): Promise<{ result: T; avgTime: number; minTime: number; maxTime: number; times: number[] }> {\n const times: number[] = [];\n let finalResult: T | undefined;\n\n for (let i = 0; i < iterations; i++) {\n const start = performance.now();\n const result = await fn();\n const end = performance.now();\n\n if (i === 0) finalResult = result;\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 return {\n result: finalResult!,\n avgTime,\n minTime,\n maxTime,\n times,\n };\n }\n\n /**\n * 尝试触发垃圾回收(如果可用)\n */\n static tryGarbageCollect(): void {\n if (typeof global !== 'undefined' && (global as any).gc) {\n try {\n (global as any).gc();\n } catch (error) {\n // 忽略GC错误\n }\n }\n }\n\n /**\n * 确保在内存测量前清理环境\n */\n static prepareForMemoryMeasurement(): void {\n // 触发GC(如果可用)\n this.tryGarbageCollect();\n\n // 给GC一些时间\n if (typeof setImmediate !== 'undefined') {\n // 使用setImmediate让事件循环有机会处理GC\n return;\n }\n }\n\n /**\n * 获取内存使用情况(在清理后)\n */\n static getMemoryUsage(): NodeJS.MemoryUsage | null {\n this.prepareForMemoryMeasurement();\n if (typeof process !== 'undefined' && process.memoryUsage) {\n return process.memoryUsage();\n }\n return null;\n }\n\n /**\n * 测量内存使用增长\n */\n static async measureMemoryUsage<T>(fn: () => Promise<T> | T): Promise<{\n result: T;\n memoryBefore: NodeJS.MemoryUsage | null;\n memoryAfter: NodeJS.MemoryUsage | null;\n heapUsedDiff: number | null;\n }> {\n // 清理环境并获取初始内存\n this.prepareForMemoryMeasurement();\n const memoryBefore = this.getMemoryUsage();\n\n // 执行函数\n const result = await fn();\n\n // 再次清理环境并获取最终内存\n this.prepareForMemoryMeasurement();\n const memoryAfter = this.getMemoryUsage();\n\n // 计算内存差异\n let heapUsedDiff: number | null = null;\n if (\n memoryBefore &&\n memoryAfter &&\n memoryBefore.heapUsed !== undefined &&\n memoryAfter.heapUsed !== undefined\n ) {\n heapUsedDiff = memoryAfter.heapUsed - memoryBefore.heapUsed;\n }\n\n return {\n result,\n memoryBefore,\n memoryAfter,\n heapUsedDiff,\n };\n }\n\n /**\n * 格式化字节大小\n */\n static formatBytes(bytes: number): string {\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n if (bytes === 0) return '0 Bytes';\n if (isNaN(bytes)) return 'NaN';\n\n const sign = bytes < 0 ? '-' : '';\n const absBytes = Math.abs(bytes);\n\n if (absBytes < 1024) {\n return `${sign}${absBytes} ${sizes[0]}`;\n }\n\n const i = Math.floor(Math.log(absBytes) / Math.log(1024));\n const value = Math.round((absBytes / Math.pow(1024, i)) * 100) / 100;\n return `${sign}${value} ${sizes[i]}`;\n }\n\n /**\n * 格式化时间\n */\n static formatTime(ms: number): string {\n if (ms < 1) return `${ms.toFixed(3)}ms`;\n if (ms < 1000) return `${ms.toFixed(2)}ms`;\n return `${(ms / 1000).toFixed(2)}s`;\n }\n}\n"]}
|
|
@@ -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"]}
|