From 06db37640e9932f9d2595ffa7c3cefe2204326db Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 6 Aug 2021 17:15:46 +0200 Subject: [PATCH] perf: do bulk read --- .../src/crypto/workers/cryptoApi.ts | 4 +- .../crypto/workers/cryptoImplementation.ts | 38 ++++++++++--------- .../src/operations/withdraw.ts | 10 +---- packages/taler-wallet-core/src/util/query.ts | 11 ++++++ packages/taler-wallet-core/src/util/timer.ts | 11 +++--- 5 files changed, 40 insertions(+), 34 deletions(-) diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts index 546099777..da92e83c6 100644 --- a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts +++ b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts @@ -82,7 +82,7 @@ interface WorkItem { /** * Time when the work was submitted to a (non-busy) worker thread. */ - startTime: number; + startTime: BigInt; } /** @@ -291,7 +291,7 @@ export class CryptoApi { resolve, reject, rpcId, - startTime: 0, + startTime: BigInt(0), }; if (this.numBusy === this.workers.length) { diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts index f799fd6e7..61134ef6b 100644 --- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts @@ -106,8 +106,8 @@ function amountToBuffer(amount: AmountJson): Uint8Array { if (typeof dvbuf.setBigUint64 !== "undefined") { dvbuf.setBigUint64(0, BigInt(amount.value)); } else { - const arr = bigint(amount.value).toArray(2 ** 8).value - let offset = 8 - arr.length + const arr = bigint(amount.value).toArray(2 ** 8).value; + let offset = 8 - arr.length; for (let i = 0; i < arr.length; i++) { dvbuf.setUint8(offset++, arr[i]); } @@ -126,9 +126,12 @@ function timestampRoundedToBuffer(ts: Timestamp): Uint8Array { const s = BigInt(tsRounded.t_ms) * BigInt(1000); v.setBigUint64(0, s); } else { - const s = (tsRounded.t_ms === "never" ? bigint.zero : bigint(tsRounded.t_ms).times(1000)); - const arr = s.toArray(2 ** 8).value - let offset = 8 - arr.length + const s = + tsRounded.t_ms === "never" + ? bigint.zero + : bigint(tsRounded.t_ms).times(1000); + const arr = s.toArray(2 ** 8).value; + let offset = 8 - arr.length; for (let i = 0; i < arr.length; i++) { v.setUint8(offset++, arr[i]); } @@ -139,7 +142,7 @@ function timestampRoundedToBuffer(ts: Timestamp): Uint8Array { class SignaturePurposeBuilder { private chunks: Uint8Array[] = []; - constructor(private purposeNum: number) { } + constructor(private purposeNum: number) {} put(bytes: Uint8Array): SignaturePurposeBuilder { this.chunks.push(Uint8Array.from(bytes)); @@ -317,7 +320,8 @@ export class CryptoImplementation { .build(); const sig = decodeCrock(denom.masterSig); const pub = decodeCrock(masterPub); - return eddsaVerify(p, sig, pub); + const res = eddsaVerify(p, sig, pub); + return res; } isValidWireAccount( @@ -550,14 +554,14 @@ export class CryptoImplementation { } benchmark(repetitions: number): BenchmarkResult { - let time_hash = 0; + let time_hash = BigInt(0); for (let i = 0; i < repetitions; i++) { const start = timer.performanceNow(); this.hashString("hello world"); time_hash += timer.performanceNow() - start; } - let time_hash_big = 0; + let time_hash_big = BigInt(0); for (let i = 0; i < repetitions; i++) { const ba = randomBytes(4096); const start = timer.performanceNow(); @@ -565,14 +569,14 @@ export class CryptoImplementation { time_hash_big += timer.performanceNow() - start; } - let time_eddsa_create = 0; + let time_eddsa_create = BigInt(0); for (let i = 0; i < repetitions; i++) { const start = timer.performanceNow(); createEddsaKeyPair(); time_eddsa_create += timer.performanceNow() - start; } - let time_eddsa_sign = 0; + let time_eddsa_sign = BigInt(0); const p = randomBytes(4096); const pair = createEddsaKeyPair(); @@ -585,7 +589,7 @@ export class CryptoImplementation { const sig = eddsaSign(p, pair.eddsaPriv); - let time_eddsa_verify = 0; + let time_eddsa_verify = BigInt(0); for (let i = 0; i < repetitions; i++) { const start = timer.performanceNow(); eddsaVerify(p, sig, pair.eddsaPub); @@ -595,11 +599,11 @@ export class CryptoImplementation { return { repetitions, time: { - hash_small: time_hash, - hash_big: time_hash_big, - eddsa_create: time_eddsa_create, - eddsa_sign: time_eddsa_sign, - eddsa_verify: time_eddsa_verify, + hash_small: Number(time_hash), + hash_big: Number(time_hash_big), + eddsa_create: Number(time_eddsa_create), + eddsa_sign: Number(time_eddsa_sign), + eddsa_verify: Number(time_eddsa_verify), }, }; } diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 99d8d7d39..44e626110 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -306,15 +306,7 @@ export async function getCandidateWithdrawalDenoms( return await ws.db .mktx((x) => ({ denominations: x.denominations })) .runReadOnly(async (tx) => { - return tx.denominations.indexes.byExchangeBaseUrl - .iter(exchangeBaseUrl) - .filter((d) => { - return ( - (d.status === DenominationStatus.Unverified || - d.status === DenominationStatus.VerifiedGood) && - !d.isRevoked - ); - }); + return tx.denominations.indexes.byExchangeBaseUrl.getAll(exchangeBaseUrl); }); } diff --git a/packages/taler-wallet-core/src/util/query.ts b/packages/taler-wallet-core/src/util/query.ts index b76bf6b6b..a95cbf1ff 100644 --- a/packages/taler-wallet-core/src/util/query.ts +++ b/packages/taler-wallet-core/src/util/query.ts @@ -35,6 +35,7 @@ import { IDBKeyPath, } from "@gnu-taler/idb-bridge"; import { Logger } from "@gnu-taler/taler-util"; +import { performanceNow } from "./timer.js"; const logger = new Logger("query.ts"); @@ -298,6 +299,7 @@ export function describeIndex( interface IndexReadOnlyAccessor { iter(query?: IDBValidKey): ResultStream; get(query: IDBValidKey): Promise; + getAll(query: IDBValidKey, count?: number): Promise; } type GetIndexReadOnlyAccess = { @@ -307,6 +309,7 @@ type GetIndexReadOnlyAccess = { interface IndexReadWriteAccessor { iter(query: IDBValidKey): ResultStream; get(query: IDBValidKey): Promise; + getAll(query: IDBValidKey, count?: number): Promise; } type GetIndexReadWriteAccess = { @@ -484,6 +487,10 @@ function makeReadContext( .openCursor(query); return new ResultStream(req); }, + getAll(query, count) { + const req = tx.objectStore(storeName).index(indexName).getAll(query, count); + return requestToPromise(req); + } }; } ctx[storeAlias] = { @@ -526,6 +533,10 @@ function makeWriteContext( .openCursor(query); return new ResultStream(req); }, + getAll(query, count) { + const req = tx.objectStore(storeName).index(indexName).getAll(query, count); + return requestToPromise(req); + } }; } ctx[storeAlias] = { diff --git a/packages/taler-wallet-core/src/util/timer.ts b/packages/taler-wallet-core/src/util/timer.ts index a7fe7dd70..7c849fbcc 100644 --- a/packages/taler-wallet-core/src/util/timer.ts +++ b/packages/taler-wallet-core/src/util/timer.ts @@ -78,24 +78,23 @@ class TimeoutHandle { } /** - * Get a performance counter in milliseconds. + * Get a performance counter in nanoseconds. */ -export const performanceNow: () => number = (() => { +export const performanceNow: () => bigint = (() => { // @ts-ignore if (typeof process !== "undefined" && process.hrtime) { return () => { - const t = process.hrtime(); - return t[0] * 1e9 + t[1]; + return process.hrtime.bigint(); }; } // @ts-ignore if (typeof performance !== "undefined") { // @ts-ignore - return () => performance.now(); + return () => BigInt(performance.now()) * BigInt(1000 * 1000); } - return () => 0; + return () => BigInt(0); })(); /**