From 53eff408c1151e884d62d13f2796a6d1fb3ca638 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 11:20:09 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20optimize=20compareVersions?= =?UTF-8?q?=20with=20single-pass=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced array split and map allocations in compareVersions with direct character scanning. This eliminates temporary array and string garbage during release version sorting, dependency resolution, and changelog delta filtering. Co-authored-by: TheDragonSoft <75906592+TheDragonSoft@users.noreply.github.com> --- src/lib/format.ts | 49 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/lib/format.ts b/src/lib/format.ts index 345259d..8da774b 100644 --- a/src/lib/format.ts +++ b/src/lib/format.ts @@ -19,13 +19,50 @@ export function percent(received: number, total: number): number { return Math.min(100, Math.round((received / total) * 100)); } -/** Compare "1.2.10" vs "1.2.9" numerically per segment. Good enough for mod versions. */ +/** + * Compare "1.2.10" vs "1.2.9" numerically per segment. + * Single-pass numerical segment parsing without array splits or `.map(parseInt)` allocations. + * Highly effective during version sorting in release selection, dependency resolution, and changelog filters. + */ export function compareVersions(a: string, b: string): number { - const pa = a.split(".").map((s) => parseInt(s, 10) || 0); - const pb = b.split(".").map((s) => parseInt(s, 10) || 0); - for (let i = 0; i < Math.max(pa.length, pb.length); i++) { - const diff = (pa[i] ?? 0) - (pb[i] ?? 0); - if (diff !== 0) return diff; + let i = 0; + let j = 0; + const lenA = a.length; + const lenB = b.length; + + while (i < lenA || j < lenB) { + let numA = 0; + while (i < lenA && a.charCodeAt(i) >= 48 && a.charCodeAt(i) <= 57) { + numA = numA * 10 + (a.charCodeAt(i) - 48); + i++; + } + + let numB = 0; + while (j < lenB && b.charCodeAt(j) >= 48 && b.charCodeAt(j) <= 57) { + numB = numB * 10 + (b.charCodeAt(j) - 48); + j++; + } + + if (numA !== numB) { + return numA - numB; + } + + // Skip any non-digit suffix in current segment (e.g., "-beta") up to the next dot + while (i < lenA && a.charCodeAt(i) !== 46) { + i++; + } + while (j < lenB && b.charCodeAt(j) !== 46) { + j++; + } + + // Skip dot + if (i < lenA && a.charCodeAt(i) === 46) { + i++; + } + if (j < lenB && b.charCodeAt(j) === 46) { + j++; + } } + return 0; }