Skip to content

Commit bd00bfb

Browse files
authored
Merge pull request #206 from githubnext/autoloop/tsb-perf-evolve
[Autoloop] [Autoloop: tsb-perf-evolve]
2 parents d6ca76a + 8d1d4a3 commit bd00bfb

1 file changed

Lines changed: 20 additions & 5 deletions

File tree

src/core/series.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -716,25 +716,40 @@ export class Series<T extends Scalar = Scalar> {
716716
const vals = this._values;
717717

718718
// Pre-partition NaN/null/undefined from finite values in one pass.
719-
// This removes the NaN check from the comparator's hot path.
719+
// fvals stores numeric values by original row index so the sort comparator
720+
// can read a typed Float64Array (not a generic T[]) at index a/b.
720721
const finBuf = new Uint32Array(n);
721722
const nanBuf = new Uint32Array(n);
723+
const fvals = new Float64Array(n);
722724
let finCount = 0;
723725
let nanCount = 0;
726+
let allNumeric = true;
724727
for (let i = 0; i < n; i++) {
725728
const v = vals[i];
726729
if (v === null || v === undefined || (typeof v === "number" && Number.isNaN(v))) {
727730
nanBuf[nanCount++] = i;
728731
} else {
732+
if (typeof v === "number") {
733+
fvals[i] = v;
734+
} else {
735+
allNumeric = false;
736+
}
729737
finBuf[finCount++] = i;
730738
}
731739
}
732740

733-
// Sort the finite-index slice in-place using an indirect comparator.
734-
// Dispatching to one of two monomorphic comparators avoids a per-call
735-
// branch on `ascending` inside the sort's hot loop.
741+
// Sort the finite-index slice in-place.
742+
// For all-numeric data use the Float64Array subtraction comparator —
743+
// monomorphic, branchless, and JIT-specialisable.
744+
// For mixed/string data fall back to the generic branch comparator.
736745
const finSlice = finBuf.subarray(0, finCount);
737-
if (ascending) {
746+
if (allNumeric) {
747+
if (ascending) {
748+
finSlice.sort((a, b) => fvals[a]! - fvals[b]!);
749+
} else {
750+
finSlice.sort((a, b) => fvals[b]! - fvals[a]!);
751+
}
752+
} else if (ascending) {
738753
finSlice.sort((a, b) => {
739754
const av = vals[a] as number | string | boolean;
740755
const bv = vals[b] as number | string | boolean;

0 commit comments

Comments
 (0)