Skip to content

Micro-optimizations to reduce dup/free#1436

Merged
saghul merged 5 commits intomasterfrom
opt-dup-free
Apr 2, 2026
Merged

Micro-optimizations to reduce dup/free#1436
saghul merged 5 commits intomasterfrom
opt-dup-free

Conversation

@saghul
Copy link
Copy Markdown
Contributor

@saghul saghul commented Mar 31, 2026

Some benchmark results (my system was not fully idle, so there might be some noise, I made several runs):

Micro-benchmarks (targeted)

  ┌─────────────────────────┬──────────┬───────────┬────────┐
  │        Benchmark        │ Baseline │ Optimized │ Change │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ Array.includes (object) │ ~117 ms  │ ~68 ms    │ -42%   │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ Array.indexOf (string)  │ ~320 ms  │ ~246 ms   │ -23%   │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ Object.is (objects)     │ ~85 ms   │ ~74 ms    │ -13%   │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ Object.isFrozen         │ ~59 ms   │ ~57 ms    │ -3%    │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ Object.isSealed         │ ~59 ms   │ ~57 ms    │ -3%    │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ === strings             │ ~73 ms   │ ~72 ms    │ -2%    │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ String() on strings     │ ~97 ms   │ ~97 ms    │ ~same  │
  ├─────────────────────────┼──────────┼───────────┼────────┤
  │ propertyIsEnumerable    │ ~62 ms   │ ~62 ms    │ ~same  │
  └─────────────────────────┴──────────┴───────────┴────────┘

  Kraken 1.1 (lower is better)

  ┌────────────────────────┬──────────┬───────────┬────────┐
  │       Benchmark        │ Baseline │ Optimized │ Change │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ ai-astar               │ 2329 ms  │ 1582 ms   │ -32%   │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ audio-beat-detection   │ 1329 ms  │ 1236 ms   │ -7%    │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ audio-dft              │ 1058 ms  │ 998 ms    │ -6%    │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ audio-fft              │ 1153 ms  │ 1133 ms   │ -2%    │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ imaging-gaussian-blur  │ 7307 ms  │ 7301 ms   │ ~same  │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ stanford-crypto-pbkdf2 │ 877 ms   │ 863 ms    │ -2%    │
  ├────────────────────────┼──────────┼───────────┼────────┤
  │ Total                  │ 19367 ms │ 18406 ms  │ -5%    │
  └────────────────────────┴──────────┴───────────┴────────┘

  SunSpider 1.0 (lower is better)

  ┌───────┬──────────┬───────────┬────────┐
  │       │ Baseline │ Optimized │ Change │
  ├───────┼──────────┼───────────┼────────┤
  │ Total │ 670 ms   │ 658 ms    │ -2%    │
  └───────┴──────────┴───────────┴────────┘

  V8 Benchmark (higher is better)

  ┌───────┬──────────┬───────────┬────────┐
  │       │ Baseline │ Optimized │ Change │
  ├───────┼──────────┼───────────┼────────┤
  │ Score │ 1349     │ 1348      │ ~same  │
  └───────┴──────────┴───────────┴────────┘

Micro-bench script:

bench_refcount.js

@saghul saghul marked this pull request as ready for review March 31, 2026 13:41
saghul added 5 commits April 2, 2026 11:33
The equality comparison functions (js_strict_eq2, js_strict_eq,
js_same_value, js_same_value_zero) are pure read-only operations that
don't need to own the values being compared. Change them to take
JSValueConst (borrowed) instead of JSValue (owned), eliminating
unnecessary js_dup/JS_FreeValue pairs.
When the input is already a JS_TAG_STRING, return it directly
instead of going through JS_ToString (which dups) + JS_FreeValue
(which frees the original), saving a redundant dup+free pair.
Extend JS_GetOwnPropertyInternal with a pflags out-parameter so callers
that only need property flags can skip the js_dup of value/getter/setter
fields. When desc is NULL and pflags is non-NULL, only the flags are
written.
Add JS_DefinePropertyValueConst, JS_DefinePropertyValueInt64Const,
and JS_CreateDataPropertyUint32Const that borrow their val parameter
instead of consuming it. This eliminates unnecessary js_dup/JS_FreeValue
pairs at call sites where callers were duping values only to have
them immediately freed by the property definition function.
When the input is already an object, return it directly instead of
going through JS_ToObject (which dups it) and then JS_FreeValue
(which frees it), avoiding a pointless refcount increment/decrement.
@saghul saghul merged commit 95fc452 into master Apr 2, 2026
122 checks passed
@saghul saghul deleted the opt-dup-free branch April 2, 2026 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants