Skip to content

perf: Pre-expand the Override type and avoid Object.entries in the override scan (~1.9x)#2

Draft
jeswr wants to merge 1 commit into
masterfrom
perf/override-scan
Draft

perf: Pre-expand the Override type and avoid Object.entries in the override scan (~1.9x)#2
jeswr wants to merge 1 commit into
masterfrom
perf/override-scan

Conversation

@jeswr

@jeswr jeswr commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

Micro-optimization of the override scan that runs before every instantiation: ConfigPreprocessorOverride.findOverrideTargets() iterates every resource in the shared RdfObjectLoader — 15,814 resources during a Community Solid Server default-config boot — to find oo:Override resources.

Two avoidable per-resource costs:

  1. resource.isA(IRIS_OO.Override) was called with a string, so Resource#isA re-ran term expansion for every resource in the loader. IRIS_OO.Override is a constant absolute IRI: it is now converted to a term once, outside the loop.
  2. Object.entries(...) materialized a [ key, value ] pair array per resource purely for iteration; Object.keys(...) + index lookup avoids that allocation.

Behaviour

Unchanged: isA(term) is exactly what isA(string) does after expanding the string; iteration order and the returned override set are identical (verified on the real boot graph: identical, empty, override set for the zero-override default config). Full suite green, 100 % coverage retained.

Measurements

Isolated A/B on the real CSS boot object graph (15,814 resources / 38k quads, warm, median of 40 reps, pss-solid-test 2-core shared box nice -n 18, both arms in the same run, this branch's build):

variant median min
original (Object.entries + isA(string)) 23.6 ms 20.4 ms
pre-expanded term + Object.keys 12.4 ms 11.6 ms

~1.9× on the scan (−11 ms per boot). The same A/B on the componentsjs 5.5.1 stack measured 24.9 → 12.6 ms. Honest framing: this is a small absolute win (the whole true-instantiate slice of a CSS boot is ~330 ms), but it was the single biggest componentsjs-owned CPU frame in the instantiate-phase profile, and it is pure waste for the common zero-override configuration.


Generated by an agent (Claude Fable 5) on @jeswr's behalf — staged on the fork for his review before upstreaming.

Review timing: This draft was prepared with Claude; I (@jeswr) will personally review it before it progresses. I'm currently batching a lot of work in flight, so expect active review Wednesday–Friday (8–10 July).

…erride scan

ConfigPreprocessorOverride.findOverrideTargets() scans every resource in
the shared RdfObjectLoader (15,814 resources during a Community Solid
Server default-config boot) to find oo:Override resources. Two avoidable
costs per boot:

1. `resource.isA(IRIS_OO.Override)` is called with a *string*, so
   Resource#isA re-runs term expansion for every resource in the loader.
   IRIS_OO.Override is a constant absolute IRI, so it can be converted
   to a term once, outside the loop.
2. `Object.entries(...)` materializes a [ key, value ] pair array per
   resource purely for iteration; `Object.keys(...)` + index lookup
   avoids that allocation.

Behaviour is unchanged: `isA(term)` is exactly what `isA(string)` does
after expanding the string, and iteration order and results are
identical.

Isolated A/B on the real CSS boot object graph (15,814 resources, warm,
median of 40 reps, 2-core shared box, this branch's build):

    original (Object.entries + isA(string)) : 23.6 ms (min 20.4)
    pre-expanded term + Object.keys         : 12.4 ms (min 11.6)  ~1.9x

The optimized scan returns the identical (empty) override set for the
default config, and the full test suite (including all override tests)
is unchanged and green. Small in absolute terms, but it is the single
biggest componentsjs-owned CPU frame in the instantiate phase and is
pure waste for the common zero-override configuration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant