Skip to content

Commit 6220ffb

Browse files
[Autoloop: tsb-perf-evolve] Iteration 71: boolean naLast precomputation for cache-hit hot path
Hypothesis: computing naLast=naPosition==="last" once as a boolean lets the JIT constant-fold it across the ternary select and the cold path, replacing string comparisons with faster bool ops on all four cache-slot lookups. Run: https://github.com/githubnext/tsb/actions/runs/26909627448 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 50bf8b4 commit 6220ffb

1 file changed

Lines changed: 11 additions & 10 deletions

File tree

src/core/series.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -757,13 +757,14 @@ export class Series<T extends Scalar = Scalar> {
757757

758758
/** Return a new Series sorted by values. */
759759
sortValues(ascending = true, naPosition: "first" | "last" = "last"): Series<T> {
760-
// ── Per-instance cache: flat 4-if chain reads property first, then validates
761-
// naPosition — lets the JIT constant-fold the dominant (ascending=true,
762-
// naPosition="last") case to a single property read and return.
763-
if (ascending && this._svCacheAL !== null && naPosition === "last") return this._svCacheAL;
764-
if (ascending && this._svCacheAF !== null && naPosition === "first") return this._svCacheAF;
765-
if (!ascending && this._svCacheDL !== null && naPosition === "last") return this._svCacheDL;
766-
if (!ascending && this._svCacheDF !== null && naPosition === "first") return this._svCacheDF;
760+
// ── Per-instance cache: pre-compute naLast boolean so the hot-path ternary
761+
// select uses bool ops (faster than string comparisons on subsequent checks)
762+
// and the JIT can constant-fold naLast across the entire function body.
763+
const naLast = naPosition === "last";
764+
const hit = ascending
765+
? (naLast ? this._svCacheAL : this._svCacheAF)
766+
: (naLast ? this._svCacheDL : this._svCacheDF);
767+
if (hit !== null) return hit;
767768

768769
const n = this._values.length;
769770
const vals = this._values;
@@ -941,7 +942,7 @@ export class Series<T extends Scalar = Scalar> {
941942
const perm = _permBuf;
942943
const outData = _outBuf as unknown as T[];
943944
let pos = 0;
944-
if (naPosition === "first") {
945+
if (!naLast) {
945946
for (let i = 0; i < nanCount; i++) {
946947
const idx = nanBuf[i]!;
947948
perm[pos] = idx;
@@ -1058,13 +1059,13 @@ export class Series<T extends Scalar = Scalar> {
10581059
});
10591060
// Save to per-instance cache so repeat calls are O(1).
10601061
if (ascending) {
1061-
if (naPosition === "last") {
1062+
if (naLast) {
10621063
this._svCacheAL = result;
10631064
} else {
10641065
this._svCacheAF = result;
10651066
}
10661067
} else {
1067-
if (naPosition === "last") {
1068+
if (naLast) {
10681069
this._svCacheDL = result;
10691070
} else {
10701071
this._svCacheDF = result;

0 commit comments

Comments
 (0)