From b97b30cddf7e92eac42e908745a9812011d0f3ff Mon Sep 17 00:00:00 2001 From: advaith Date: Mon, 9 Sep 2024 01:53:25 -0700 Subject: [PATCH] perf(snowflake): optimize Snowflake.timestampFrom (#792) * Optimize Snowflake.timestampFrom * edit based on feedback --- packages/snowflake/src/lib/Snowflake.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/snowflake/src/lib/Snowflake.ts b/packages/snowflake/src/lib/Snowflake.ts index e9716bff5c..564860f50b 100644 --- a/packages/snowflake/src/lib/Snowflake.ts +++ b/packages/snowflake/src/lib/Snowflake.ts @@ -1,5 +1,6 @@ const IncrementSymbol = Symbol('@sapphire/snowflake.increment'); const EpochSymbol = Symbol('@sapphire/snowflake.epoch'); +const EpochNumberSymbol = Symbol('@sapphire/snowflake.epoch.number'); const ProcessIdSymbol = Symbol('@sapphire/snowflake.processId'); const WorkerIdSymbol = Symbol('@sapphire/snowflake.workerId'); @@ -18,6 +19,8 @@ export const MaximumProcessId = 0b11111n; */ export const MaximumIncrement = 0b111111111111n; +const TimestampFieldDivisor = 2 ** 22; + /** * A class for generating and deconstructing Twitter snowflakes. * @@ -44,6 +47,12 @@ export class Snowflake { */ private readonly [EpochSymbol]: bigint; + /** + * Internal reference of the epoch passed in the constructor as a number + * @internal + */ + private readonly [EpochNumberSymbol]: number; + /** * Internal incrementor for generating snowflakes * @internal @@ -67,15 +76,23 @@ export class Snowflake { */ public constructor(epoch: number | bigint | Date) { this[EpochSymbol] = BigInt(epoch instanceof Date ? epoch.getTime() : epoch); + this[EpochNumberSymbol] = Number(this[EpochSymbol]); } /** - * The epoch for this snowflake + * The epoch for this snowflake, as a bigint */ public get epoch(): bigint { return this[EpochSymbol]; } + /** + * The epoch for this snowflake, as a number + */ + public get epochNumber(): number { + return this[EpochNumberSymbol]; + } + /** * Gets the configured process ID */ @@ -173,7 +190,7 @@ export class Snowflake { * @returns The UNIX timestamp that is stored in `id`. */ public timestampFrom(id: string | bigint): number { - return Number((BigInt(id) >> 22n) + this[EpochSymbol]); + return Math.floor(Number(id) / TimestampFieldDivisor) + this[EpochNumberSymbol]; } /**