undefect. CWE-407 — 92 sites, 42 ecosystems

B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections.
Squash of 94 local commits onto remote master.
This commit is contained in:
russell@unturf.com 2026-03-26 19:48:18 -04:00
parent 0a580b313d
commit db29a08762
1311 changed files with 371202 additions and 1188 deletions

View file

@ -1 +1,8 @@
8e7823aa15f60f048df6fda42a65aee2 undefect-cwe407-2026-03-26.pdf
33dc45d94dcb2b6cec4f7036497571d7 executive-summary.pdf
ba0de5d1546aa2971492f74616f13f47 full-paper.pdf
3fda5736a004c621f52701c92a7ca7f5 undefect-cwe407-2026-03-24.pdf
f076f22e9e70a94f51884562aad6fdc5 undefect-cwe407-2026-03-25.pdf
5da33a4087fdca81f70cce84656afc7f undefect-cwe407-2026-03-26.pdf
ff52abf9f47a7e6bb25e4519b1325090 undefect-minecraft-enterprise-java-2026-03-24.pdf
c7fe499eb004271b384a31ac01b38852 undefect-minecraft-enterprise-java-2026-03-25.pdf
818d29731df88333d29cfdd3eefeb3a2 undefect-minecraft-enterprise-java-2026-03-26.pdf

View file

@ -1,5 +1,6 @@
<div class="cover">
<div class="cover-title">undefect.</div>
<hr class="cover-title-rule">
<div class="cover-subtitle">CWE-407 · The Sedimentary Defect</div>
<div class="cover-subtitle">Quadratic Complexity in Graph Traversal Infrastructure</div>
<div class="cover-date">2026-03-24 · Internal draft — not for external distribution</div>
@ -38,8 +39,8 @@ A single well-crafted implementation serves as the genetic blueprint.
4. **Harvest Stage:** Mature implementations compile into comprehensive documentation, ready for use
Code propagates according to its kind — clean architecture begets clean implementations,
elegant solutions inspire elegant variations. The process of generating 63 validated
defect patches across 27 ecosystems in a single research wave demonstrates how truth,
elegant solutions inspire elegant variations. The process of generating 92 validated
defect patches across 42 ecosystems in a single research wave demonstrates how truth,
properly seeded, multiplies. Each tested patch validates the correctness of the original
diagnosis & extends light into new programming paradigms.
@ -93,7 +94,7 @@ coding time to clear specification of requirements, rigorous validation of outpu
thoughtful direction of focus. The practitioner becomes gardener rather than builder.
Directing growth rather than manually constructing. Harvesting rather than manufacturing.
This project seeded 63 patches. Each patch carries a `// CWE-407 fix` comment — a
This project seeded 91 patches. Each patch carries a `// CWE-407 fix` comment — a
signature in the corpus of every compiler, runtime, and build tool it touches. As
projects fork, downstream copies propagate, & package managers distribute updates, the
fix self-propagates. The seed outlasts the gardener.
@ -127,7 +128,7 @@ Suppose technology already exists, but has not yet found creative linkage in pro
orientation.
A single structural error — a list used where a set belongs, inside a graph traversal
loop — is present in 63 confirmed sites across 27 software ecosystems. Every affected
loop — is present in 92 confirmed sites across 42 software ecosystems. Every affected
system maintains a `visited` or `onStack` collection to track nodes during graph
traversal. In every defective site, that collection is implemented as a list. Membership
is tested by linear scan. The result is O(n²) or worse behavior in code that should run
@ -138,7 +139,15 @@ TypeScript type-check of a large codebase, every `pip install` of a project with
dependency graph, every MongoDB query plan enumeration on a collection with many indexes,
every OSPF topology change on a network with hundreds of nodes, every Apache Kafka
consumer group rebalance, every Spring Boot hierarchical context bean resolution, every
webpack hot module replacement cycle, and every Presto optimizer pass over wide row types.
webpack hot module replacement cycle, every Presto optimizer pass over wide row types,
every ONOS SDN topology event, every BIRD OSPF SPF and BGP convergence, every Bazel
monorepo analysis phase, every OpenDaylight switch reconciliation, every Apache httpd
sticky-session route lookup, every KiCad DRC from-to path, every V8 JIT function
compilation, every SpiderMonkey Ion bounds-check, every `terraform plan`, every Ansible
role compilation, every Jenkins dependency graph rebuild, every Maven multi-module build,
every CFEngine `unique()` policy call, every SaltStack cloud map deployment, every
NetworkX cycle enumeration, and every Gremlin `.simplePath()`/`.cyclicPath()` traversal
step in any TinkerPop-backed graph database.
It has persisted for decades because the code is correct — a list and a set both answer
the membership question — and because it degrades at the scale where most developers never
work.
@ -150,7 +159,7 @@ the missing linkages, applied them, tested them, and benchmarked them across eve
confirmed site — compiler, routing, database, build tool, event streaming, web framework,
query optimizer, and browser runtime.
**63 sites patched.** 3 deferred (PostgreSQL -0001/-0005; MongoDB -0005 IndexBounds).
**92 sites patched.** 3 deferred (PostgreSQL -0001/-0005; MongoDB -0005 IndexBounds).
1 fixable-upstream (Erlang OTP). 1 fixable-pending (swipl-0003). 2 not-worth-fixing.
3 unpatched (Minecraft, Create mod). No language left behind.
@ -248,6 +257,9 @@ stacks, Spark schemas — this is the dominant build cost.
| ghc-0003 | GHC | `Graph/Ops.hs:637``elem color neighbourColors` register allocator | **PATCHED** |
| kotlin-0001 | Kotlin compiler | `NonExpansiveInheritanceRestrictionChecker.kt:150``in List` post-DFS | **PATCHED** |
| llvm-0001 | LLVM | `GlobalsModRef.cpp:570``is_contained(vector<CGN*>)` LTO | **PATCHED** |
| llvm-0002 | LLVM | `AliasSetTracker.cpp:278``SmallVector<MemoryLocation>+is_contained()` dedup per alias set merge; O(N²) over memory accesses | **PATCHED** |
| v8-0001 | V8 | `register-allocator.cc:2324``ZoneVector<TopLevelLiveRange*>+std::find` in `MeetConstraintsBefore()`; O(k²) spill dedup per instruction | **PATCHED** |
| tinkerpop-0001 | Apache TinkerPop | `process/traversal/Path.java:206` — default `isSimple()` O(n²) nested loop; fired by every `.simplePath()`/`.cyclicPath()` Gremlin step via `subPath()``MutablePath` | **PATCHED** |
| rustc-0001 | rustc | `inhabited_predicate.rs:109,127``SmallVec::contains` | **PATCHED** |
| erlang-0001 | Erlang OTP | `digraph.erl:578``lists:member(V, Xs)` in `one_path/8` | **PATCHED** |
| swipl-0001 | SWI-Prolog | `ugraphs.pl:510``graph_memberchk` O(|V|) scan in `top_sort` | **PATCHED** |
@ -297,6 +309,36 @@ stacks, Spark schemas — this is the dominant build cost.
| webpack-0001 | webpack | `lib/hmr/JavascriptHotModuleReplacement.runtime.js:74``Array.indexOf` BFS visited set in `getAffectedModuleEffects` | **PATCHED** |
| webpack-0002 | webpack | `JavascriptHotModuleReplacement.runtime.js:101``Array.indexOf` in `addAllToSet` dedup accumulator | **PATCHED** |
| webpack-0003 | webpack | `lib/hmr/HotModuleReplacement.runtime.js:60,67``parents.indexOf` / `children.indexOf` in hot require path | **PATCHED** |
| onos-0001 | ONOS (SDN) | `utils/misc/.../graph/TarjanGraphSearch.java:160``ArrayList<VertexData>.contains()` in SCC edge traversal, O(V×E); fires every topology change event | **PATCHED** |
| bird-0001 | BIRD routing | `proto/ospf/rt.c:1980``WALK_LIST` insertion sort as Dijkstra priority queue, O(E×V); BIRD ships `lib/heap.h` unused here | **PATCHED** |
| bird-0002 | BIRD routing | `nest/a-set.c:190``int_set_contains` linear scan per BGP community lookup; 100M+ calls/convergence at internet scale | **PATCHED** |
| bazel-0001 | Bazel | `analysis/AspectCollection.java:332``ArrayList<Aspect>` backwards scan in `validateDuplicateAspect()`; O(n²) per aspect propagation path | **PATCHED** |
| bazel-0002 | Bazel | `analysis/AspectCollection.java:294``deps.keySet()` full iteration grows per step in `create()` double loop; O(n²) per dependency edge | **PATCHED** |
| odl-0001 | OpenDaylight | `frm/impl/DevicesGroupRegistry.java:21``ArrayList<Uint32>.contains()` in group reconciliation loop; fires every switch connect/reconnect | **PATCHED** |
| httpd-0001 | Apache httpd | `modules/proxy/mod_proxy_balancer.c:216,542``strcmp` scan over worker array per sticky-session request; O(W) per request | **PATCHED** |
| kicad-0001 | KiCad | `pcbnew/connectivity/from_to_cache.cpp:66``std::vector<CN_ITEM*>` linear scan in BFS visited-check; O(V²×B) per DRC from-to path | **PATCHED** |
| llvm-0003 | LLVM | `Transforms/Utils/LCSSA.cpp:70``SmallVectorImpl<BasicBlock*>+is_contained()` in exit-block worklist; O(U×X) per loop | **PATCHED** |
| spidermonkey-0001 | SpiderMonkey | `jit/IonAnalysis.cpp:~1997``Vector<LinearTerm,2>` linear scan in `LinearSum::add()`; O(N×T) Ion bounds-check elimination | **PATCHED** |
| rabbitmq-0001 | RabbitMQ | `rabbit_classic_queue.erl:410``lists:member(Pid, pending)` over unconfirmed message map on publisher DOWN; O(M×P) | **PATCHED** |
| octave-0001 | GNU Octave | `data.cc:138` + `numeric/max.cc:111``std::find` on already-sorted `vecdim` vector; `std::binary_search` is correct | **PATCHED** |
| cfengine-0001 | CFEngine | `libpromises/evalfunction.c:3656``RlistKeyIn(keys)` O(K) linked-list walk per `getindices()` iteration; O(K²) total | **PATCHED** |
| cfengine-0003 | CFEngine | `evalfunction.c:4407``RlistAppendScalarIdemp` O(R) scan per `maparray()` mapped value | **PATCHED** |
| puppet-0001 | Puppet | `graph/simple_graph.rb:199``frame[1].member?` on growing Array in `paths_in_cycle`; O(\|cycle\|³) error-path | **PATCHED** |
| ansible-0002 | Ansible | `playbook/role/__init__.py:285``self.collections.extend(...if c not in self.collections)` list scan | **PATCHED** |
| saltstack-0001 | SaltStack | `cloud/__init__.py:1830``_has_loop(seen=[])` list DFS with `list(seen)` copy at each level; O(V²) cloud map | **PATCHED** |
| terraform-0002 | Terraform | `internal/dag/graph.go:79``EdgesTo` iterates all edges O(E) inside vertex loop → O(V×E); `CBDEdgeTransformer` | **PATCHED** |
| networkx-0001 | NetworkX | `algorithms/cycles.py:812``B = defaultdict(list)` in `recursive_simple_cycles`; `not in` O(\|B\|) per edge | **PATCHED** |
| rubocop-0001 | RuboCop | `cop/ignored_node.rb:32``@ignored_nodes = []``part_of_ignored_node?` scans Array per `on_str` node | **PATCHED** |
| solargraph-0001 | Solargraph | `source/chain.rb:38``@@inference_stack = []``include?` per pin + shared class variable (thread-safety defect) | **PATCHED** |
| solargraph-0002 | Solargraph | `api_map/constants.rb:262``skip.to_a` Array subtraction in recursive `inner_get_constants` | **PATCHED** |
### HIGH — Infrastructure orchestration hot paths
| ID | Tool | Location | Status |
|----|------|----------|--------|
| terraform-0001 | Terraform | `internal/dag/tarjan.go:96``inStack []Vertex` O(V) linear scan per edge in Tarjan SCC; fires on every `terraform plan`/`apply` | **PATCHED** |
| cfengine-0002 | CFEngine | `evalfunction.c:5783``unique()` built-in: `RlistAppendScalarIdemp` O(N²) on full list input; `unique()` used on hostname/filepath lists in fleet policies | **PATCHED** |
| ansible-0001 | Ansible | `playbook/role/__init__.py:529``seen = []` role dependency dedup; O(D²) where D = transitive dep count; fires per-role per-play | **PATCHED** |
### LOW — Principle violations, bounded input
@ -305,6 +347,11 @@ stacks, Spark schemas — this is the dominant build cost.
| maven-0001 | Maven | `project/Graph.java:63``ArrayList.remove()` in `removeEdge` | **PATCHED** |
| maven-0002 | Maven | `internal/impl/Graph.java:63` — duplicate of maven-0001 | **PATCHED** |
| maven-0003 | Maven | `project/Graph.java:102``LinkedList.lastIndexOf` in cycle reporter | **PATCHED** |
| maven-0004 | Maven | `DefaultGraphBuilder.java:161,193,294``sortedProjects.indexOf()` in 3 sort calls | **PATCHED** |
| maven-0005 | Maven | `lifecycle/internal/builder/BuildPlanLogger.java:79``sortedNodes().indexOf()` per-step | **PATCHED** |
| jenkins-0001 | Jenkins | `DependencyGraph.java:325``ArrayList<DependencyGroup>` linear scan in `add()` edge dedup | **PATCHED** |
| jenkins-0002 | Jenkins | `AbstractProject.java:1651``getChildJobs()` returns `List<Job>` scanned per upstream project | **PATCHED** |
| rubocop-0002 | RuboCop | `cop/style/redundant_self.rb:62``@allowed_send_nodes = []``include?` per `on_send` call | **PATCHED** |
| cmake-0001 | CMake | `cmComputeLinkDepends.cxx:1167,521,1363``std::find` on group vectors | **PATCHED** |
| swift-0001 | Swift | `RewriteContext.cpp:454` — assert-only, debug builds | NOT-WORTH-FIXING |
| debian-0001 | Debian | `DebianLinux.pm:140` — config parse, 6-item list | NOT-WORTH-FIXING |
@ -322,7 +369,7 @@ where D is the depth of the diamond chain. For a diamond of depth 10, that is 2^
1,024 redundant node visits per edge check. Large modpacks produce diamond dependency
chains with depths in this range.
**63 sites patched. 3 deferred (PostgreSQL -0001/-0005; MongoDB -0005 IndexBounds). 1 fixable-upstream (Erlang OTP — sltab patch). 1 fixable-pending (swipl-0003 attr_unify_hook). 2 not-worth-fixing. 3 unpatched (Minecraft, Create mod).**
**92 sites patched. 3 deferred (PostgreSQL -0001/-0005; MongoDB -0005 IndexBounds). 1 fixable-upstream (Erlang OTP — sltab patch). 1 fixable-pending (swipl-0003 attr_unify_hook). 2 not-worth-fixing. 3 unpatched (Minecraft, Create mod).**
---
@ -637,22 +684,23 @@ top of O(|V|³) algorithm — memberchk is not the dominant term.
Browsers are among the largest and most performance-critical C++/Rust codebases on the
planet. All three major engines are affected by patches already in this map.
**Firefox** is a three-way beneficiary. It compiles with Clang and enables LLVM LTO in
all release builds, so llvm-0001 (GlobalsModRef call-graph traversal) applies directly
to every Firefox release build. Its Rust codebase — WebRender (GPU compositor), Stylo
(CSS engine), Servo components — means rustc-0001 (match exhaustiveness checker) and
rustc-0002 (specialization graph) both apply. TypeScript is used in Firefox DevTools and
the web-ext tooling, so ts-0001 through ts-0003 apply there as well. SpiderMonkey
IonMonkey was scanned and is **CLEAN** — it uses hash containers throughout its JIT
pipeline.
**Firefox** is a four-way beneficiary. It compiles with Clang and enables LLVM LTO in
all release builds, so llvm-0001/0002/0003 (GlobalsModRef + AliasSet + LCSSA) apply
directly to every Firefox release build. Its Rust codebase means rustc-0001/0002 apply.
TypeScript applies via Firefox DevTools and web-ext tooling (ts-0001 through ts-0003).
SpiderMonkey IonMonkey has **sm-0001**`LinearSum::add()` in Ion bounds-check
elimination used a `Vector<LinearTerm,2>` with O(N×T) linear scan instead of a HashMap.
The main paths use `js::HashSet/HashMap` correctly; sm-0001 is in the Ion analysis pass
that fires on every JIT-compiled function with multiple add/subtract expressions.
**Chrome / Chromium** is the largest single beneficiary of llvm-0001. Chromium is ~35M
lines of code compiled with Clang and full LTO in release builds. The GlobalsModRef
call-graph traversal runs across that entire binary. LTO build time is a documented
bottleneck for the Chromium team; the fix is directly material. V8 TurboFan was scanned
and is **CLEAN**. TypeScript is used in Chrome DevTools, the Chrome Extensions API, and
web platform test tooling; npm arborist patches apply to the Chromium web tooling
dependency graph.
**Chrome / Chromium** is the largest single beneficiary of llvm-0001/0002/0003. Chromium
is ~35M lines of code compiled with Clang and full LTO in release builds. V8 has
**v8-0001** — `MeetConstraintsBefore()` in the register allocator used a
`ZoneVector<TopLevelLiveRange*>` with O(k²) deduplication scan per instruction; the fix
is `ZoneUnorderedSet` (50× speedup at k=50 distinct spill ranges). This fires on every
function compiled by V8's optimizing compiler — millions of function compilations per
browser session. TypeScript applies via Chrome DevTools and Extensions API (ts-00010003);
npm arborist patches apply to Chromium web tooling dependency graphs.
**Safari / WebKit** compiles with Clang and LTO, so llvm-0001 applies. The WebKit build
system uses CMake, so cmake-0001 applies. JavaScriptCore (JSC) has not yet been scanned;
@ -666,8 +714,8 @@ a reduction in one of the most expensive single passes in the release build pipe
| Engine | Browser | Scan result |
|--------|---------|-------------|
| V8 TurboFan | Chrome | **CLEAN** |
| SpiderMonkey IonMonkey | Firefox | **CLEAN** |
| V8 TurboFan | Chrome | **v8-0001 PATCHED** — `ZoneVector` dedup in register allocator (50×) |
| SpiderMonkey IonMonkey | Firefox | **sm-0001 PATCHED** — `LinearSum::add()` HashMap (O(N×T)→O(N)) |
| JavaScriptCore | Safari | Not yet scanned |
### 7.8 C/C++ Ecosystem — GCC, LLVM, CMake
@ -802,18 +850,87 @@ but becomes more important as deployment velocity increases.
### 8.4 CI/CD and Cloud Infrastructure
**Jenkins** — **jenkins-0001/0002 PATCHED.** Jenkins' `DependencyGraph.add()` scanned
a `List<DependencyGroup>` on every `addDependency()` call during `rebuildDependencyGraph()`
— triggered on every job save, rename, or delete. O(P×D) per rebuild, O(D) per edge.
Fix: parallel `Map<AbstractProject, Map<AbstractProject, DependencyGroup>>` index for
O(1) edge lookup. Also: `getBuildTriggerUpstreamProjects()` called `getChildJobs(ap).contains(this)`
where `getChildJobs` returns `List<Job>` — O(U×D) per call. Fix: convert to `HashSet`
first. Jenkins is the dominant CI system in enterprise Java shops; `rebuildDependencyGraph`
fires thousands of times daily in large installations.
**Maven** — **maven-0004/0005 PATCHED.** `DefaultGraphBuilder.java` used
`sortedProjects::indexOf` as a sort comparator key in three places — O(N² log N) per
Maven build invocation for the reactor setup pass. For a 500-module reactor: 2.25M list
probes vs 500 map lookups. Fix: `Map<MavenProject, Integer>` index built once. maven-0005
is the build-plan logger (debug path only).
**Terraform** — **tf-0001/0002 PATCHED.** `AcyclicGraph.Validate()` calls `Cycles()`
on every `terraform plan` and `terraform apply`. Tarjan's SCC used `inStack(s.Stack, w)`
— O(V) slice scan — instead of an `onStack map[Vertex]bool`. O(V×E) → O(E). `EdgesTo()`
in `CBDEdgeTransformer` scanned the entire edge set O(E) inside a vertex loop O(V×E
total); fix uses the already-maintained `upEdges` index. tf-0001 fires on every
infrastructure deployment. Unit test: 100× at V=100, exact triangular count confirmed.
**Ansible** — **ans-0001/0002 PATCHED.** `Role.get_vars()` used `seen = []` for
transitive role dependency deduplication — O(D²) where D = transitive dep count. Ansible
codebase had a `TODO: re-examine dep loading` comment acknowledging the problem. Fix:
`seen_ids = set()` using `id(dep)` (Role is unhashable). ans-0002: `self.collections`
list membership tests — parallel set added. Fires per-role per-play during playbook
compilation. Unit test: 30× at D=80.
**SaltStack** — **salt-0001 PATCHED.** `_has_loop()` in `salt/cloud/__init__.py` used
`seen = list`, `list(seen)` copy at every recursion level for cloud machine dependency
cycle detection. O(V²) + O(depth²) copy overhead. Fix: `seen = set()`. 39× at depth=80.
**Docker image builds** — Python base images: `pip install -r requirements.txt` in
Dockerfile layers is the dominant time sink in most CI pipelines. distlib-0001 and
cpython-0001 together reduce this. Maven/Gradle Java CI pipelines benefit from javac
patches. npm install benefits from arborist patches.
and maven-0004/0005 patches. npm install benefits from arborist patches.
**At scale:** GitHub Actions processes approximately 50M workflow runs per month. If each
Java, Python, or TypeScript workflow saves 515 seconds of build time, the aggregate is
millions of compute-hours per month. This is real cost and real carbon.
**Serverless cold starts** — AWS Lambda Python runtime: pip-installed dependencies ship
in the Lambda layer; faster resolution produces smaller, simpler layers and faster cold
starts. Lambda Java runtime: javac inference improvements are baked into compiled JARs.
**CFEngine** — **cfe-0001/0002/0003 PATCHED.** `getindices()`, `unique()`, and
`maparray()` all used `RlistAppendScalarIdemp()` — which calls `RlistKeyIn()`, an O(N)
linked-list walk — as a dedup primitive. `unique()` is a first-class CFEngine policy
built-in; fleet-management policies call it on hostname lists of N=10,000+. O(N²) → O(N)
via `StringSet`. cfe-0002 (unique) is HIGH severity. All three defects share the same
root: `rlist.c:542`. Unit test: 39× at N=80 for unique, 15× at K=60 for getindices.
**RuboCop / Solargraph** — **rubocop-0001/0002, solargraph-0001/0002 PATCHED.** RuboCop's
`IgnoredNode` mixin used `@ignored_nodes = []` (Array) for a dedup set included in every
cop via `Cop::Base`. `part_of_ignored_node?` scanned it linearly for every string literal
in the file — O(R×S) where R = regexp count, S = string count. Fix: `Set.new.compare_by_identity`.
Solargraph's `@@inference_stack = []` (class variable) was both O(depth) for membership
and a data race across threads; replaced with thread-local `Set.new`.
### 8.5 Graph Traversal Frameworks
**Apache TinkerPop** — **tinkerpop-0001 PATCHED.** TinkerPop's `Path.java:206-214`
contains an O(n²) default `isSimple()` implementation: a nested double-loop over the
path's object list comparing every pair of vertices. This fires on every traverser
evaluated by the `.simplePath()` and `.cyclicPath()` Gremlin steps — the fundamental
graph deduplication operations in any Gremlin-based graph database (JanusGraph,
Amazon Neptune, Azure Cosmos DB Gremlin API, TinkerGraph).
The defect is activated through a specific code path: `PathFilterStep.java:60,62`
calls `traverser.path().subPath(fromLabel, toLabel)`, which materializes a `MutablePath`
via the `Path.java:263` default `subPath()`. `MutablePath` has no override for
`isSimple()`, so it falls through to the O(n²) default. Separately,
`PathFilterStep.java:79` hits the same path via `byPath.isSimple()` whenever `by()`
modulators are present.
The correct implementation already exists in the same file: `ImmutablePath.isSimple()`
at line 292 uses a HashSet and is O(n). The fix is to bring the default `isSimple()`
up to the same standard — a single HashSet pass instead of a nested loop.
**Proof:** `TinkerPopPathTest` measures comparison operations directly. At path length
n=200: defective does n×(n-1)/2 = 19,900 comparisons; fixed does n = 200. **99.5×
speedup at n=200.** Growth is exactly quadratic vs linear, confirmed at n=10, 25, 50,
100, 200. Every Gremlin `.simplePath()` or `.cyclicPath()` query pays this O(n²) tax
per traverser per step evaluated against a path of length n.
---
@ -831,18 +948,23 @@ dataset; they subsample, they approximate, they accept that "large graphs are sl
NetworkX is the dominant pure-Python graph library, used in bioinformatics, social
network analysis, quantum circuit simulation, ML pipeline graphs, and physics simulations.
It implements Tarjan SCC, Kosaraju SCC, DFS, topological sort, cycle detection, dominator
trees, and dozens of other graph algorithms entirely in Python — a codebase that predates
the widespread adoption of O(1)-first idioms.
trees, and dozens of other graph algorithms entirely in Python.
**Scan result: CLEAN** (scanned 2026-03-23). `cycle_basis()`, `simple_cycles()`,
`_johnson_cycle_search()`, and all DFS/BFS implementations use `set()` or `dict`
throughout. Every `in visited` check is O(1). No CWE-407 candidates across the entire
`algorithms/` package.
**nx-0001 — PATCHED** (`algorithms/cycles.py:812`). `recursive_simple_cycles()`
Johnson's elementary cycle algorithm — uses `B = defaultdict(list)` as a blocking-set
accumulator. Inside `circuit()`, every `if thisnode not in B[nextnode]` check is O(|B|)
on a plain list. The fix is `B = defaultdict(set)` with `.add()` replacing `.append()`,
making the membership test O(1). The code even has a comment: `# TODO: use set for
speedup?` — the defect was known but unfixed.
This is a meaningful negative result. NetworkX appears to have been modernized — the
Python `set` idiom is native and visible, and the NetworkX developers appear to have used
it consistently. Scientific Python code that calls NetworkX algorithms on large graphs is
not paying the quadratic tax through NetworkX.
**Speedup:** O(E × |B|) → O(E). For a graph with 100 nodes and 10 elementary cycles,
the defect performs O(1,000) list scans per circuit detection; the fix performs O(10) set
lookups. Unit test confirms 25× at k=50 distinct sources, 2.68× defect growth vs 1.44×
fixed on doubling k (super-linear confirmed).
The remainder of the `algorithms/` package — `cycle_basis()`, Tarjan SCC, DFS, BFS —
all use `set()` or `dict` and are clean. Scientific Python code calling NetworkX for
large cycle enumeration problems pays the quadratic tax through this one path.
### 9.2 SciPy `csgraph`
@ -1453,13 +1575,15 @@ The following systems were scanned and confirmed free of CWE-407:
**Routing and SDN:** ONOS, OpenDaylight — both use O(1) hash containers.
**Browser engines:** V8 TurboFan, SpiderMonkey IonMonkey — both confirmed clean.
**Browser engines:** V8 (v8-0001 PATCHED); SpiderMonkey (sm-0001 PATCHED); JavaScriptCore — not yet scanned.
**Build systems:** Bazel, sbt — confirmed clean.
**Build systems:** sbt — confirmed clean. Bazel: bazel-0001/0002 PATCHED. Jenkins: jenkins-0001/0002 PATCHED.
**Scientific computing:** NetworkX, GNU Octave — confirmed clean.
**Scientific computing:** GNU Octave (octave-0001 PATCHED — `std::find` on sorted vector); NetworkX (nx-0001 PATCHED — `B=defaultdict(list)` in `recursive_simple_cycles`). SciPy: not yet scanned.
**EDA:** Yosys, Verilator, KiCad — confirmed clean.
**EDA:** Yosys, Verilator — confirmed clean. KiCad: kicad-0001 PATCHED.
**Graph databases / traversal:** Neo4j — confirmed clean (uses `HeapTrackingUnifiedMap` O(1) throughout). Apache TinkerPop: tinkerpop-0001 PATCHED (`Path.isSimple()` 99.5×).
**P2P networks:** I2P Java router, libtorrent, Transmission, Kubo (IPFS), Deluge — all
confirmed clean.
@ -1570,7 +1694,7 @@ is constant. This confirms the thesis: CWE-407 concentrates in core algorithmic
## 17. Fix Paths for Pending Sites
All actively-patchable defect sites are now patched (63 total). Remaining open items:
All actively-patchable defect sites are now patched (91 total). Remaining open items:
erlang-0002 (FIXABLE-UPSTREAM — requires OTP internal ABI change); postgresql-0001 and
-0005 (DEFERRED — structural variants pending `nodeHash()` infrastructure); mongodb-0005
(DEFERRED — IndexBounds structural equality, no available hash); mongodb-0006/-0007
@ -1917,8 +2041,11 @@ and the structural variants of -0005.
## 18. Remaining Scan Backlog
**Confirmed CLEAN (no action needed):**
ONOS, OpenDaylight, MySQL optimizer, V8 TurboFan, SpiderMonkey IonMonkey, Bazel, sbt,
GNU Octave, KiCad, Yosys, Verilator — all confirmed using O(1) hash containers.
ONOS, OpenDaylight, MySQL optimizer, Neo4j — all confirmed using O(1) hash containers.
V8 TurboFan (v8-0001 PATCHED), SpiderMonkey IonMonkey (sm-0001 PATCHED), Bazel
(bazel-0001/0002 PATCHED), GNU Octave (octave-0001 PATCHED), KiCad (kicad-0001 PATCHED),
Apache TinkerPop (tinkerpop-0001 PATCHED), Yosys, Verilator — all now scanned and
resolved.
**PostgreSQL:** -0002, -0003, -0004 patched (Bitmapset, Path B). -0001 and -0005
structural variants still DEFERRED pending `nodeHash()` infrastructure.
@ -2066,13 +2193,13 @@ language community find and fix it before the next era begins?**
The defect exists across the manifold because list-before-set is the default in every
standard library ever designed. The fix exists across the manifold because every standard
library eventually added O(1) membership containers. The missing piece — across 63
library eventually added O(1) membership containers. The missing piece — across 91
confirmed sites and an unknown number of unconfirmed ones — is not capability. It is
awareness and linkage.
This whitepaper is that linkage.
The 63 confirmed patches represent a sampling across the manifold. The methodology — scan
The 91 confirmed patches represent a sampling across the manifold. The methodology — scan
for `O(n)` membership tests inside graph traversal loops, measure the ratio, apply the
one-line fix, validate by instrumentation — is language-agnostic and tool-agnostic. The
same scan that found kafka-0001 will find the equivalent defect in any language's message
@ -2198,7 +2325,7 @@ The question every language community will answer, on its own timeline, is wheth
crosses this particular finish line before the compute abundance era begins — or still
burning quadratic cycles on linear work when the era arrives.
The 63 patches in this paper represent the languages that crossed first. The methodology,
The 91 patches in this paper represent the languages that crossed first. The methodology,
the benchmarks, and the outreach briefs represent an open invitation for every other
language on the manifold to follow.
@ -2210,9 +2337,9 @@ manifold is enumerable. The fix is known. The work is bounded.
## One-Sentence Version
A list used where a set belongs, in graph traversal code written before hash containers
were idiomatic, has been running silently at O(n²) in 63 confirmed sites across
were idiomatic, has been running silently at O(n²) in 91 confirmed sites across
foundational tools — compilers, package managers, database query planners, crypto
toolchains, routing daemons, event streaming platforms, web frameworks, query optimizers,
and browser runtimes — the fix is a one-line data structure substitution with no
behavioral change, and we have patched, tested, and benchmarked every confirmed site
across 27 ecosystems.
across 42 ecosystems.

BIN
whitepaper/full-paper.pdf Normal file

Binary file not shown.

View file

@ -12,68 +12,69 @@ digraph benchmax {
labelloc=t
labeljust=l
fontsize=11
fontcolor="#555555"
fontcolor="black"
]
node [
fontname="Helvetica"
fontsize=8
style=filled
penwidth=0.4
fillcolor="white"
color="black"
penwidth=0.8
margin="0.14,0.06"
]
edge [
color="black"
penwidth=0.6
arrowsize=0.4
fontname="Helvetica"
fontsize=7
fontcolor="#999999"
fontcolor="black"
]
// Javac Tarjan — star graph
// javac Tarjan — circle size encodes speedup
subgraph cluster_javac {
label="javac Tarjan starWithBackEdges(V)"
fontsize=9
color="#e8eef8"
bgcolor="#f8faff"
penwidth=0.4
color="black"
penwidth=0.8
jv200 [label="V=200\n2.87x" shape=circle fixedsize=true width=0.55 fillcolor="#e8f5e8" color="#88cc88"]
jv400 [label="V=400\n3.87x" shape=circle fixedsize=true width=0.65 fillcolor="#d8f0d8" color="#66bb66"]
jv800 [label="V=800\n5.47x" shape=circle fixedsize=true width=0.80 fillcolor="#c8eac8" color="#44aa44"]
jv2000 [label="V=2000\n~12x" shape=circle fixedsize=true width=1.0 fillcolor="#b8e4b8" color="#339933"]
jv5000 [label="V=5000\n~30x" shape=circle fixedsize=true width=1.3 fillcolor="#a8dea8" color="#228822"]
jv200 -> jv400 -> jv800 -> jv2000 -> jv5000 [color="#88cc88"]
jv200 [label="V=200\n2.87x" shape=circle fixedsize=true width=0.55]
jv400 [label="V=400\n3.87x" shape=circle fixedsize=true width=0.65]
jv800 [label="V=800\n5.47x" shape=circle fixedsize=true width=0.80]
jv2000 [label="V=2000\n~12x" shape=circle fixedsize=true width=1.0]
jv5000 [label="V=5000\n~30x" shape=circle fixedsize=true width=1.3]
jv200 -> jv400 -> jv800 -> jv2000 -> jv5000
}
// Minecraft DependencySorter — diamond depth
// Minecraft DependencySorter — circle size encodes speedup, thick border = EXPONENTIAL
subgraph cluster_mc {
label="minecraft-0001 diamond depth D"
fontsize=9
color="#f8e8e8"
bgcolor="#fff8f8"
penwidth=0.4
color="black"
penwidth=1.5
style=dashed
md8 [label="D=8\n4x" shape=circle fixedsize=true width=0.55 fillcolor="#fce8e8" color="#e88888"]
md10 [label="D=10\n11.7x" shape=circle fixedsize=true width=0.75 fillcolor="#fad8d8" color="#e06060"]
md12 [label="D=12\n31.5x" shape=circle fixedsize=true width=1.0 fillcolor="#f8c8c8" color="#d84444"]
md14 [label="D=14\n88x" shape=circle fixedsize=true width=1.4 fillcolor="#f5b8b8" color="#cc2222"]
md16 [label="D=16\nOVERFLOW" shape=circle fixedsize=true width=1.8 fillcolor="#f0a0a0" color="#aa0000" fontcolor="#880000"]
md8 -> md10 -> md12 -> md14 -> md16 [color="#e88888"]
md8 [label="D=8\n4x" shape=circle fixedsize=true width=0.55]
md10 [label="D=10\n11.7x" shape=circle fixedsize=true width=0.75]
md12 [label="D=12\n31.5x" shape=circle fixedsize=true width=1.0]
md14 [label="D=14\n88x" shape=circle fixedsize=true width=1.4 penwidth=2.0]
md16 [label="D=16\nOVERFLOW" shape=circle fixedsize=true width=1.8 penwidth=2.5 style="filled,dashed"]
md8 -> md10 -> md12 -> md14 -> md16 [penwidth=1.5]
}
// Create TrackGraph — V nodes
// Create TrackGraph — circle size encodes speedup
subgraph cluster_create {
label="create-0001 TrackGraph BFS ArrayList.remove(0)"
fontsize=9
color="#f0eeee"
bgcolor="#fdfafa"
penwidth=0.4
color="black"
penwidth=0.8
cv100 [label="V=100\n~1.5x" shape=circle fixedsize=true width=0.5 fillcolor="#f5f0ee" color="#ccaaaa"]
cv500 [label="V=500\n~6x" shape=circle fixedsize=true width=0.7 fillcolor="#f0e8e8" color="#cc8888"]
cv2000 [label="V=2000\n~25x" shape=circle fixedsize=true width=1.1 fillcolor="#ead8d8" color="#cc6666"]
cv5000 [label="V=5000\n~60x" shape=circle fixedsize=true width=1.5 fillcolor="#e4c8c8" color="#bb4444"]
cv100 -> cv500 -> cv2000 -> cv5000 [color="#ccaaaa"]
cv100 [label="V=100\n~1.5x" shape=circle fixedsize=true width=0.5]
cv500 [label="V=500\n~6x" shape=circle fixedsize=true width=0.7]
cv2000 [label="V=2000\n~25x" shape=circle fixedsize=true width=1.1]
cv5000 [label="V=5000\n~60x" shape=circle fixedsize=true width=1.5]
cv100 -> cv500 -> cv2000 -> cv5000
}
// Cross arrows showing relationship

View file

@ -13,60 +13,61 @@ digraph complexity {
fontname="Helvetica"
fontsize=8
style=filled
penwidth=0.4
fillcolor="white"
color="black"
penwidth=0.8
shape=box
margin="0.15,0.07"
]
edge [
color="#cccccc"
penwidth=0.5
color="black"
penwidth=0.6
arrowsize=0.4
fontname="Helvetica"
fontsize=7
fontcolor="#999999"
fontcolor="black"
]
// BEFORE column
// BEFORE column — dashed border to mark defective
subgraph cluster_before {
label="BEFORE"
fontsize=10
fontcolor="#cc4444"
color="#f5dddd"
bgcolor="#fffafa"
penwidth=0.4
fontcolor="black"
color="black"
penwidth=1.5
style=dashed
b_exp [label="O(E^D)\nexponential\nDependencySorter" fillcolor="#fce8e8" color="#e88888"]
b_cub [label="O(n³)\nscala3 constraint" fillcolor="#fde8d8" color="#e8a888"]
b_quad [label="O(n²)\njavac Tarjan\nTypeScript checker\nCreate BFS\n..." fillcolor="#fef0e0" color="#e8cc88"]
b_med [label="O(n·k)\nbounded defects\ncpython, gcc..." fillcolor="#f8f8e8" color="#cccc88"]
b_exp [label="O(E^D)\nexponential\nDependencySorter" penwidth=2.5]
b_cub [label="O(n³)\nscala3 constraint" penwidth=2.0]
b_quad [label="O(n²)\njavac Tarjan\nTypeScript checker\nCreate BFS\n..." penwidth=1.5]
b_med [label="O(n·k)\nbounded defects\ncpython, gcc..." penwidth=0.8]
}
// AFTER column
// AFTER column — solid border to mark fixed
subgraph cluster_after {
label="AFTER"
fontsize=10
fontcolor="#338833"
color="#ddeedd"
bgcolor="#f8fdf8"
penwidth=0.4
fontcolor="black"
color="black"
penwidth=1.5
a_lin [label="O(E)\nper isCyclic call\nvisited set" fillcolor="#e8f5e8" color="#88cc88"]
a_quad2[label="O(n²)\nscala3 still complex\nbut inner loop O(1)" fillcolor="#eef5e8" color="#aacc88"]
a_lin2 [label="O(V+E)\nTarjan fixed\nArrayDeque BFS" fillcolor="#e8f5e8" color="#88cc88"]
a_lin3 [label="O(n)\nbounded + O(1) check" fillcolor="#f0f5e8" color="#aabb88"]
a_lin [label="O(E)\nper isCyclic call\nvisited set"]
a_quad2[label="O(n²)\nscala3 still complex\nbut inner loop O(1)" style="filled,dashed"]
a_lin2 [label="O(V+E)\nTarjan fixed\nArrayDeque BFS"]
a_lin3 [label="O(n)\nbounded + O(1) check"]
}
// Arrows — fix transitions
b_exp -> a_lin [label="add visited set" color="#88cc88" penwidth=1.0 style=bold]
b_cub -> a_quad2[label="inner O(1)" color="#aacc88" penwidth=0.8]
b_quad -> a_lin2 [label="Set / ArrayDeque" color="#88cc88" penwidth=1.0 style=bold]
b_med -> a_lin3 [label="HashSet" color="#aabb88" penwidth=0.8]
// Arrows — penwidth encodes speedup magnitude
b_exp -> a_lin [label="add visited set" penwidth=2.0 style=bold]
b_cub -> a_quad2[label="inner O(1)" penwidth=1.2]
b_quad -> a_lin2 [label="Set / ArrayDeque" penwidth=2.0 style=bold]
b_med -> a_lin3 [label="HashSet" penwidth=1.2]
// Speedup labels on right
s1 [label="88x at depth 14\n∞ at depth 16" shape=plaintext fontsize=8 fontcolor="#cc4444"]
s2 [label="— (still O(n²))\nbut bounded" shape=plaintext fontsize=8 fontcolor="#888888"]
s3 [label="23x at V=800\n401x fewer comparisons" shape=plaintext fontsize=8 fontcolor="#338833"]
s4 [label="24x typical" shape=plaintext fontsize=8 fontcolor="#888888"]
s1 [label="88x at depth 14\n\u221e at depth 16" shape=plaintext fontsize=8 fontcolor="black"]
s2 [label="— (still O(n²))\nbut bounded" shape=plaintext fontsize=8 fontcolor="black"]
s3 [label="23x at V=800\n401x fewer comparisons" shape=plaintext fontsize=8 fontcolor="black"]
s4 [label="24x typical" shape=plaintext fontsize=8 fontcolor="black"]
a_lin -> s1 [style=invis]
a_quad2-> s2 [style=invis]

View file

@ -13,92 +13,90 @@ digraph defect_map {
fontname="Helvetica"
fontsize=9
style=filled
penwidth=0.5
fillcolor="white"
color="black"
penwidth=0.8
margin="0.12,0.06"
]
edge [
color="#bbbbbb"
color="black"
penwidth=0.6
arrowsize=0.5
fontname="Helvetica"
fontsize=8
fontcolor="#888888"
fontcolor="black"
]
// Severity clusters
// Severity clusters — border thickness encodes severity; dashed = not-yet-fixed
subgraph cluster_exp {
label="EXPONENTIAL"
fontsize=9
fontcolor="#cc4444"
color="#f5dddd"
bgcolor="#fffafa"
penwidth=0.5
mc1 [label="minecraft-0001\nDependencySorter\nO(E^D)" fillcolor="#fce8e8" color="#e88888"]
fontcolor="black"
color="black"
penwidth=2.5
style=dashed
mc1 [label="minecraft-0001\nDependencySorter\nO(E^D)" penwidth=2.5]
}
subgraph cluster_critical {
label="CRITICAL O(n³)"
label="CRITICAL O(n\u00b3)"
fontsize=9
fontcolor="#cc6600"
color="#f5ead5"
bgcolor="#fffcf5"
penwidth=0.5
sc1 [label="scala3-0001\nConstraint lattice" fillcolor="#fef0dc" color="#e8aa66"]
fontcolor="black"
color="black"
penwidth=2.0
sc1 [label="scala3-0001\nConstraint lattice" penwidth=2.0]
}
subgraph cluster_high {
label="HIGH O(n²)"
label="HIGH O(n\u00b2)"
fontsize=9
fontcolor="#558855"
color="#ddeedd"
bgcolor="#f8fdf8"
penwidth=0.5
jc1 [label="javac-0001\nTarjan stack" fillcolor="#e8f5e8" color="#88bb88"]
jc2 [label="javac-0002a/b\nInfer closure" fillcolor="#e8f5e8" color="#88bb88"]
jc45 [label="javac-0004/5\nDeps+Context" fillcolor="#e8f5e8" color="#88bb88"]
ts [label="ts-0001..3\nTypeScript checker" fillcolor="#eaf0f8" color="#88aacc"]
ghc [label="ghc-0001..3\nSCC/codegen" fillcolor="#f0eaf8" color="#aa88cc"]
kt [label="kotlin-0001\nInheritance check" fillcolor="#eaf0f8" color="#88aacc"]
ll [label="llvm-0001\nGlobalsModRef" fillcolor="#f8f0ea" color="#cc9966"]
rc [label="rustc-0001\nSmallVec::contains" fillcolor="#f8eeea" color="#cc8866"]
er1 [label="erlang-0001\none_path/8" fillcolor="#f5f0e8" color="#bbaa66"]
fr1 [label="frrouting-0001\nospf_ti_lfa ×5" fillcolor="#eaf5f0" color="#66bb99"]
fr2 [label="frrouting-0002\nospf_spf Dijkstra\n⚠ UNPATCHED" fillcolor="#fff0f0" color="#cc6666" style="filled,dashed"]
pg [label="postgresql-0001..5\nplanner hot paths\nDEFERRED ×5" fillcolor="#f8f8ee" color="#aaaa66" style="filled,dashed"]
cr1 [label="create-0001\nTrackGraph BFS\nArrayList.remove(0)" fillcolor="#fce8e8" color="#e88888" style="filled,dashed"]
fontcolor="black"
color="black"
penwidth=1.5
jc1 [label="javac-0001\nTarjan stack" penwidth=1.5]
jc2 [label="javac-0002a/b\nInfer closure" penwidth=1.5]
jc45 [label="javac-0004/5\nDeps+Context" penwidth=1.5]
ts [label="ts-0001..3\nTypeScript checker" penwidth=1.5]
ghc [label="ghc-0001..3\nSCC/codegen" penwidth=1.5]
kt [label="kotlin-0001\nInheritance check" penwidth=1.5]
ll [label="llvm-0001\nGlobalsModRef" penwidth=1.5]
rc [label="rustc-0001\nSmallVec::contains" penwidth=1.5]
er1 [label="erlang-0001\none_path/8" penwidth=1.5]
fr1 [label="frrouting-0001\nospf_ti_lfa x5" penwidth=1.5]
fr2 [label="frrouting-0002\nospf_spf Dijkstra\n[UNPATCHED]" penwidth=1.5 style="filled,dashed"]
pg [label="postgresql-0001..5\nplanner hot paths\n[DEFERRED x5]" penwidth=1.0 style="filled,dashed"]
cr1 [label="create-0001\nTrackGraph BFS\nArrayList.remove(0)" penwidth=1.5 style="filled,dashed"]
}
subgraph cluster_med {
label="MEDIUM"
fontsize=9
fontcolor="#666688"
color="#e8e8f0"
bgcolor="#fafafa"
penwidth=0.5
jc3 [label="javac-0003\nModuleHasher" fillcolor="#eeeef8" color="#9999cc"]
gcc [label="gcc-0001\nJohnson's gcov" fillcolor="#eeeef8" color="#9999cc"]
rc2 [label="rustc-0002\nspec graph" fillcolor="#eeeef8" color="#9999cc"]
cp [label="cpython-0001\nsccutils.py" fillcolor="#eeeef8" color="#9999cc"]
er2 [label="erlang-0002\nloop_vertices\nFIXABLE-UPSTREAM" fillcolor="#f5f0ff" color="#aa88dd" style="filled,dashed"]
mc2 [label="minecraft-0002\nPistonResolver\nbounded≤12" fillcolor="#f8f8f8" color="#aaaaaa" style="filled,dashed"]
fontcolor="black"
color="black"
penwidth=1.0
jc3 [label="javac-0003\nModuleHasher"]
gcc [label="gcc-0001\nJohnson's gcov"]
rc2 [label="rustc-0002\nspec graph"]
cp [label="cpython-0001\nsccutils.py"]
er2 [label="erlang-0002\nloop_vertices\n[FIXABLE-UPSTREAM]" style="filled,dashed"]
mc2 [label="minecraft-0002\nPistonResolver\nbounded<=12" style="filled,dashed"]
}
subgraph cluster_low {
label="LOW"
fontsize=9
fontcolor="#999999"
color="#eeeeee"
bgcolor="#fefefe"
fontcolor="black"
color="black"
penwidth=0.5
mv [label="maven-0001..3" fillcolor="#f5f5f5" color="#cccccc"]
cm [label="cmake-0001" fillcolor="#f5f5f5" color="#cccccc"]
sq [label="sqlite-0001" fillcolor="#f5f5f5" color="#cccccc"]
co [label="composer-0001..2" fillcolor="#f5f5f5" color="#cccccc"]
mv [label="maven-0001..3" penwidth=0.5]
cm [label="cmake-0001" penwidth=0.5]
sq [label="sqlite-0001" penwidth=0.5]
co [label="composer-0001..2" penwidth=0.5]
}
// Fix status edges
jc1 -> er1 [label="pattern" style=dotted]
jc1 -> er2 [label="same fix\n(parallel set)" style=dotted]
fr1 -> fr2 [label="same package" color="#e88888"]
mc1 -> pg [label="tag→plan\nboth unvisited\nDFS" style=dotted color="#ccaaaa"]
fr1 -> fr2 [label="same package"]
mc1 -> pg [label="tag->plan\nboth unvisited\nDFS" style=dotted]
}

View file

@ -14,80 +14,70 @@ digraph javac_speedup {
labelloc=t
labeljust=l
fontsize=11
fontcolor="#555555"
fontcolor="black"
]
node [
fontname="Helvetica"
fontsize=8
style=filled
penwidth=0.4
fillcolor="white"
color="black"
penwidth=0.8
margin="0.15,0.08"
shape=box
]
edge [
color="#cccccc"
color="black"
penwidth=0.8
arrowsize=0.5
fontname="Helvetica"
fontsize=7
fontcolor="#888888"
fontcolor="black"
]
// ── BEFORE column ────────────────────────────────────────
// ── BEFORE column — dashed border marks defective ─────────────────────────
subgraph cluster_before {
label="BEFORE (defective)"
fontsize=9
color="#eeeeee"
bgcolor="#fff8f8"
penwidth=0.5
fontcolor="#cc6666"
color="black"
penwidth=1.2
style=dashed
fontcolor="black"
b1 [label="javac-0001\nTarjan stack.contains()\nO(V²)\nV=800: 513 µs/op\n401× extra comparisons"
fillcolor="#fce8e8" color="#e88888" penwidth=1.0]
b2a [label="javac-0002a\nfindNode ArrayList scan\nO(N²)\nN=200: 67 µs/op\n101× extra comparisons"
fillcolor="#fce8e8" color="#e88888"]
b2b [label="javac-0002b\nclosure uncached DFS\nO(V·K)\nV=100,K=100: 230 µs/op\n50× extra work"
fillcolor="#fce8e8" color="#e88888"]
b3 [label="javac-0003\nTopoSorter Deque.contains()\nO(V²)\nV=200: 60 µs/op\n100× extra comparisons"
fillcolor="#fce8e8" color="#e88888"]
b4 [label="javac-0004\nDependencyList.add contains\nO(N²)\nM=200: 15 µs/op\n100× extra comparisons"
fillcolor="#fce8e8" color="#e88888"]
b5 [label="javac-0005\nBoundSet containsAll\nO(B²)\nB=100: 11 µs/op\n101× extra comparisons"
fillcolor="#fce8e8" color="#e88888"]
b1 [label="javac-0001\nTarjan stack.contains()\nO(V\u00b2)\nV=800: 513 us/op\n401x extra comparisons"
penwidth=1.5]
b2a [label="javac-0002a\nfindNode ArrayList scan\nO(N\u00b2)\nN=200: 67 us/op\n101x extra comparisons"]
b2b [label="javac-0002b\nclosure uncached DFS\nO(V\u00b7K)\nV=100,K=100: 230 us/op\n50x extra work"]
b3 [label="javac-0003\nTopoSorter Deque.contains()\nO(V\u00b2)\nV=200: 60 us/op\n100x extra comparisons"]
b4 [label="javac-0004\nDependencyList.add contains\nO(N\u00b2)\nM=200: 15 us/op\n100x extra comparisons"]
b5 [label="javac-0005\nBoundSet containsAll\nO(B\u00b2)\nB=100: 11 us/op\n101x extra comparisons"]
}
// ── AFTER column ─────────────────────────────────────────
// ── AFTER column — solid border marks fixed ───────────────────────────────
subgraph cluster_after {
label="AFTER (fixed)"
fontsize=9
color="#eeeeee"
bgcolor="#f5fff5"
penwidth=0.5
fontcolor="#448844"
color="black"
penwidth=1.2
fontcolor="black"
a1 [label="Tarjan n.active flag\nO(V+E)\nV=800: 94 µs/op\n5.46× faster"
fillcolor="#e8f8e8" color="#88cc88" penwidth=1.0]
a2a [label="HashMap lookup\nO(1)\nN=200: 10 µs/op\n6.9× faster"
fillcolor="#e8f8e8" color="#88cc88"]
a2b [label="cached DFS\nO(V+E)\nV=100: 11 µs/op\n20.9× faster"
fillcolor="#e8f8e8" color="#88cc88"]
a3 [label="HashSet.contains()\nO(1)\nV=200: 40 µs/op\n1.5× faster"
fillcolor="#e8f8e8" color="#88cc88"]
a4 [label="LinkedHashSet.add()\nO(1)\nM=200: 4 µs/op\n4.3× faster"
fillcolor="#e8f8e8" color="#88cc88"]
a5 [label="Set.equals()\nO(B)\nB=100: 5 µs/op\n2.4× faster"
fillcolor="#e8f8e8" color="#88cc88"]
a1 [label="Tarjan n.active flag\nO(V+E)\nV=800: 94 us/op\n5.46x faster"]
a2a [label="HashMap lookup\nO(1)\nN=200: 10 us/op\n6.9x faster"]
a2b [label="cached DFS\nO(V+E)\nV=100: 11 us/op\n20.9x faster"]
a3 [label="HashSet.contains()\nO(1)\nV=200: 40 us/op\n1.5x faster"]
a4 [label="LinkedHashSet.add()\nO(1)\nM=200: 4 us/op\n4.3x faster"]
a5 [label="Set.equals()\nO(B)\nB=100: 5 us/op\n2.4x faster"]
}
// ── Fix arrows ───────────────────────────────────────────
b1 -> a1 [label="5.46×" color="#cc8888" penwidth=1.2 fontcolor="#cc4444" fontsize=8]
b2a -> a2a [label="6.9×" color="#cc8888" fontcolor="#cc4444" fontsize=8]
b2b -> a2b [label="20.9×" color="#cc8888" penwidth=1.4 fontcolor="#cc4444" fontsize=8]
b3 -> a3 [label="1.5×" color="#bbbbbb" fontcolor="#888888" fontsize=8]
b4 -> a4 [label="4.3×" color="#cc8888" fontcolor="#cc4444" fontsize=8]
b5 -> a5 [label="2.4×" color="#cc8888" fontcolor="#cc4444" fontsize=8]
// ── Fix arrows — penwidth encodes speedup magnitude ───────────────────────
b1 -> a1 [label="5.46x" penwidth=1.8]
b2a -> a2a [label="6.9x" penwidth=1.4]
b2b -> a2b [label="20.9x" penwidth=2.5 style=bold]
b3 -> a3 [label="1.5x" penwidth=0.6]
b4 -> a4 [label="4.3x" penwidth=1.2]
b5 -> a5 [label="2.4x" penwidth=0.8]
// ── Ranking — force column alignment ─────────────────────
// ── Ranking — force column alignment ─────────────────────────────────────
{ rank=same; b1; a1 }
{ rank=same; b2a; a2a }
{ rank=same; b2b; a2b }

View file

@ -17,78 +17,75 @@ digraph mc_client_speedup {
labelloc=t
labeljust=l
fontsize=11
fontcolor="#555555"
fontcolor="black"
]
node [
fontname="Helvetica"
fontsize=8
style=filled
penwidth=0.4
fillcolor="white"
color="black"
penwidth=0.8
margin="0.15,0.08"
shape=box
]
edge [
color="#cccccc"
color="black"
penwidth=0.8
arrowsize=0.5
fontname="Helvetica"
fontsize=7
fontcolor="#888888"
fontcolor="black"
]
// ── Client trigger path ───────────────────────────────────
worldload [label="Single-Player\nWorld Load" shape=box fillcolor="#f0f0f8" color="#9999cc" penwidth=0.8]
gameplay [label="In-Game\n(active session)" shape=box fillcolor="#f0f0f8" color="#9999cc"]
worldload [label="Single-Player\nWorld Load" shape=box penwidth=1.0]
gameplay [label="In-Game\n(active session)" shape=box]
// ── BEFORE ───────────────────────────────────────────────
// ── BEFORE — dashed border marks defective ────────────────
subgraph cluster_before {
label="BEFORE — client defects (shared classes)"
fontsize=9
color="#eeeeee"
bgcolor="#fff8f8"
penwidth=0.5
fontcolor="#cc6666"
color="black"
penwidth=1.2
style=dashed
fontcolor="black"
b1 [label="minecraft-0001\nDependencySorter.isCyclic\nO(E^D) — tag graph on load\nDepth 14: 7,432 µs/op\nFreezes world load screen\non modpacks"
fillcolor="#fce8e8" color="#e05555" penwidth=1.4]
b2 [label="minecraft-0002\nPistonStructureResolver\nO(P²) piston activation\nP≤12, minor"
fillcolor="#f8f8f8" color="#cccccc"]
b3 [label="minecraft-0003\nExperimentalRedstoneWireEvaluator\nO(N²) — blocks game thread\nClient experiences lag spikes\non large redstone builds\n(experimental flag)"
fillcolor="#fff8e8" color="#ddcc66" penwidth=1.0]
b4 [label="minecraft-0004\nMoveThroughVillageGoal\nO(N²) villager AI\nN≤15, negligible"
fillcolor="#f8f8f8" color="#cccccc"]
b1 [label="minecraft-0001\nDependencySorter.isCyclic\nO(E^D) — tag graph on load\nDepth 14: 7,432 us/op\nFreezes world load screen\non modpacks"
penwidth=2.0]
b2 [label="minecraft-0002\nPistonStructureResolver\nO(P\u00b2) piston activation\nP<=12, minor"
penwidth=0.6]
b3 [label="minecraft-0003\nExperimentalRedstoneWireEvaluator\nO(N\u00b2) — blocks game thread\nClient experiences lag spikes\non large redstone builds\n(experimental flag)"
penwidth=1.2]
b4 [label="minecraft-0004\nMoveThroughVillageGoal\nO(N\u00b2) villager AI\nN<=15, negligible"
penwidth=0.6]
}
// ── AFTER ────────────────────────────────────────────────
// ── AFTER — solid border marks fixed ─────────────────────
subgraph cluster_after {
label="AFTER — client impact with patch applied"
fontsize=9
color="#eeeeee"
bgcolor="#f5fff5"
penwidth=0.5
fontcolor="#448844"
color="black"
penwidth=1.2
fontcolor="black"
a1 [label="HashSet visited set\nO(E) per call\n110.9× faster world load\nModpack load: seconds → ms\nNo stack overflow at depth 16+"
fillcolor="#e8f8e8" color="#55aa55" penwidth=1.4]
a2 [label="HashSet toPushSet\nO(1) per check\n~1.1× (bounded)"
fillcolor="#f5fff5" color="#aaccaa"]
a3 [label="HashSet inFrontier sets\nO(N) BFS total\nEliminates redstone\nlag spikes"
fillcolor="#e8f8e8" color="#88cc88" penwidth=1.0]
a4 [label="HashSet visitedSet\nO(1) lookup\n~1.0× (bounded)"
fillcolor="#f5fff5" color="#aaccaa"]
a1 [label="HashSet visited set\nO(E) per call\n110.9x faster world load\nModpack load: seconds -> ms\nNo stack overflow at depth 16+"]
a2 [label="HashSet toPushSet\nO(1) per check\n~1.1x (bounded)"]
a3 [label="HashSet inFrontier sets\nO(N) BFS total\nEliminates redstone\nlag spikes"]
a4 [label="HashSet visitedSet\nO(1) lookup\n~1.0x (bounded)"]
}
// ── Client flow ───────────────────────────────────────────
worldload -> b1 [label="tag resolution" color="#e88888" penwidth=1.0]
gameplay -> b2 [label="piston use" color="#cccccc"]
gameplay -> b3 [label="redstone circuit" color="#ddcc66"]
gameplay -> b4 [label="villager AI" color="#cccccc"]
worldload -> b1 [label="tag resolution" penwidth=1.5]
gameplay -> b2 [label="piston use" penwidth=0.5]
gameplay -> b3 [label="redstone circuit" penwidth=1.0]
gameplay -> b4 [label="villager AI" penwidth=0.5]
// ── Fix arrows ───────────────────────────────────────────
b1 -> a1 [label="110.9× at D=14" color="#cc3333" penwidth=1.8 fontcolor="#cc2222" fontsize=8]
b2 -> a2 [label="~1.1×" color="#cccccc" fontcolor="#aaaaaa" fontsize=8]
b3 -> a3 [label="~N× (N=wires)" color="#cc9933" penwidth=1.0 fontcolor="#886622" fontsize=8]
b4 -> a4 [label="~1.0×" color="#cccccc" fontcolor="#aaaaaa" fontsize=8]
// ── Fix arrows — penwidth encodes speedup magnitude ───────
b1 -> a1 [label="110.9x at D=14" penwidth=2.5 style=bold]
b2 -> a2 [label="~1.1x" penwidth=0.5]
b3 -> a3 [label="~Nx (N=wires)" penwidth=1.2]
b4 -> a4 [label="~1.0x" penwidth=0.5]
{ rank=same; b1; a1 }
{ rank=same; b2; a2 }
@ -96,6 +93,6 @@ digraph mc_client_speedup {
{ rank=same; b4; a4 }
// ── Key insight ──────────────────────────────────────────
note [label="Client note: same JARs, same defects.\nModpack players loading 1000+ cross-mod\ntags at diamond depth 814 experience\nworld load times of 1060s on slow hardware.\nPatch eliminates the exponential growth."
shape=note fillcolor="#f8f8ff" color="#bbbbcc" fontsize=7.5]
note [label="Client note: same JARs, same defects.\nModpack players loading 1000+ cross-mod\ntags at diamond depth 8-14 experience\nworld load times of 10-60s on slow hardware.\nPatch eliminates the exponential growth."
shape=note penwidth=0.5 fontsize=7.5]
}

View file

@ -12,33 +12,35 @@ digraph mc_gameloop {
labelloc=t
labeljust=l
fontsize=11
fontcolor="#555555"
fontcolor="black"
]
node [
fontname="Helvetica"
fontsize=8
style=filled
penwidth=0.4
fillcolor="white"
color="black"
penwidth=0.8
margin="0.12,0.06"
]
edge [
color="#cccccc"
color="black"
penwidth=0.5
arrowsize=0.4
fontname="Helvetica"
fontsize=7
fontcolor="#aaaaaa"
fontcolor="black"
]
// Server tick root
tick [label="MinecraftServer.tick()\n50ms budget / tick" shape=box fillcolor="#f0f0f8" color="#9999cc" penwidth=0.8]
// Server tick root — double border to show it's the entry point
tick [label="MinecraftServer.tick()\n50ms budget / tick" shape=box penwidth=1.5]
// Major subsystems
world [label="ServerLevel.tick()" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
chunks [label="ServerChunkCache\n.tick()" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
ents [label="Entity tick loop" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
blocks [label="Block tick\n(random + scheduled)" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
redst [label="Redstone\npropagation" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
// Major subsystems — normal border
world [label="ServerLevel.tick()" shape=box]
chunks [label="ServerChunkCache\n.tick()" shape=box]
ents [label="Entity tick loop" shape=box]
blocks [label="Block tick\n(random + scheduled)" shape=box]
redst [label="Redstone\npropagation" shape=box]
tick -> world
tick -> chunks
@ -46,47 +48,47 @@ digraph mc_gameloop {
world -> blocks
world -> redst
// Tag loading (startup, not tick — but reload)
reload [label="TagLoader\n(world load / /reload)" shape=box fillcolor="#fff0f0" color="#ddaaaa" style="filled,dashed"]
ds [label="⚠ minecraft-0001\nDependencySorter.isCyclic\nO(E^D) — no visited set\nExponential on diamond deps" shape=box fillcolor="#fce8e8" color="#e88888" penwidth=1.0]
reload -> ds [color="#e88888" penwidth=1.0 label="called per edge"]
// Tag loading (startup/reload) — dashed = not-on-tick-path
reload [label="TagLoader\n(world load / /reload)" shape=box style="filled,dashed"]
// Defective node — thick border marks confirmed defect
ds [label="[!] minecraft-0001\nDependencySorter.isCyclic\nO(E^D) — no visited set\nExponential on diamond deps" shape=box penwidth=2.0 style="filled,dashed"]
reload -> ds [penwidth=1.5 label="called per edge"]
// Piston (block tick path)
piston [label="PistonStructureResolver\n.resolve()" shape=box fillcolor="#f8f8f8" color="#cccccc"]
ps [label="minecraft-0002\ntoPush.contains()\nO(P²) bounded≤12" shape=box fillcolor="#f8f8f8" color="#cccccc" style=dashed]
// Piston (block tick path) — thin border = bounded/LOW
piston [label="PistonStructureResolver\n.resolve()" shape=box]
ps [label="minecraft-0002\ntoPush.contains()\nO(P\u00b2) bounded<=12" shape=box style="filled,dashed" penwidth=0.5]
blocks -> piston
piston -> ps [color="#cccccc" label="per activation"]
piston -> ps [penwidth=0.5 label="per activation"]
// Entity AI
ai [label="GoalSelector.tick()\nBrain.tick()" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
path [label="PathNavigation\nPathFinder" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
// Entity AI — normal
ai [label="GoalSelector.tick()\nBrain.tick()" shape=box]
path [label="PathNavigation\nPathFinder" shape=box]
ents -> ai
ai -> path
path_q [label="? scan pending\nA* open set structure" shape=box fillcolor="#fffbe8" color="#ddcc66" style=dashed]
path -> path_q [color="#ddcc66" style=dashed label="under investigation"]
path_q [label="? scan pending\nA* open set structure" shape=box style="filled,dashed" penwidth=0.5]
path -> path_q [style=dashed penwidth=0.5 label="under investigation"]
// Redstone
expredst [label=" minecraft-0003\nExperimentalRedstoneWireEvaluator\nDeque.contains() O(N) in BFS\nMEDIUM — flag-gated" shape=box fillcolor="#fff8e8" color="#ddcc66" penwidth=0.8]
redst -> expredst [color="#ddcc66" penwidth=0.8 label="experimental flag"]
// Redstone — medium border = MEDIUM defect
expredst [label="[!] minecraft-0003\nExperimentalRedstoneWireEvaluator\nDeque.contains() O(N) in BFS\nMEDIUM — flag-gated" shape=box penwidth=1.2 style="filled,dashed"]
redst -> expredst [penwidth=0.8 label="experimental flag" style=dashed]
// DefaultRedstoneWireEvaluator
defredst [label="DefaultRedstoneWireEvaluator\nCLEAN — separate Set+Deque" shape=box fillcolor="#f5fff5" color="#88cc88"]
redst -> defredst [color="#88cc88" label="default path"]
// DefaultRedstoneWireEvaluator — CLEAN
defredst [label="DefaultRedstoneWireEvaluator\nCLEAN — separate Set+Deque" shape=box penwidth=0.5]
redst -> defredst [penwidth=0.5 label="default path"]
// Chunk
chunkmap [label="ChunkMap\ndependency tracking" shape=box fillcolor="#f5f5fc" color="#aaaadd"]
chunkmap [label="ChunkMap\ndependency tracking" shape=box]
chunks -> chunkmap
// Legend
// Legend — shape-based encoding
subgraph cluster_legend {
label="Legend"
label="Key"
fontsize=8
color="#eeeeee"
bgcolor="#fafafa"
penwidth=0.3
l1 [label="⚠ confirmed defect" shape=plaintext fontsize=8 fontcolor="#e88888"]
l2 [label="bounded / LOW" shape=plaintext fontsize=8 fontcolor="#aaaaaa"]
l3 [label="? under scan" shape=plaintext fontsize=8 fontcolor="#ddcc66"]
l4 [label="not yet scanned" shape=plaintext fontsize=8 fontcolor="#aaaadd"]
color="black"
penwidth=0.5
style=dotted
l1 [label="[!] thick border = confirmed defect" shape=plaintext fontsize=8 fontcolor="black"]
l2 [label="thin border = bounded / LOW / CLEAN" shape=plaintext fontsize=8 fontcolor="black"]
l3 [label="dashed box = deferred / flag-gated / not-on-tick-path" shape=plaintext fontsize=8 fontcolor="black"]
}
}

View file

@ -14,83 +14,79 @@ digraph mc_server_speedup {
labelloc=t
labeljust=l
fontsize=11
fontcolor="#555555"
fontcolor="black"
]
node [
fontname="Helvetica"
fontsize=8
style=filled
penwidth=0.4
fillcolor="white"
color="black"
penwidth=0.8
margin="0.15,0.08"
shape=box
]
edge [
color="#cccccc"
color="black"
penwidth=0.8
arrowsize=0.5
fontname="Helvetica"
fontsize=7
fontcolor="#888888"
fontcolor="black"
]
// ── BEFORE ───────────────────────────────────────────────
// ── BEFORE — dashed border marks defective ────────────────
subgraph cluster_before {
label="BEFORE (defective)"
fontsize=9
color="#eeeeee"
bgcolor="#fff8f8"
penwidth=0.5
fontcolor="#cc6666"
color="black"
penwidth=1.2
style=dashed
fontcolor="black"
b1 [label="minecraft-0001\nDependencySorter.isCyclic\nO(E^D) EXPONENTIAL\nDepth 14: 7,432 µs/op\nDepth 16+: STACK OVERFLOW\nTrigger: world load, /reload"
fillcolor="#fce8e8" color="#e05555" penwidth=1.4]
b2 [label="minecraft-0002\nPistonStructureResolver\nO(P²) — bounded P≤12\nPiston activation"
fillcolor="#f8f8f8" color="#cccccc"]
b3 [label="minecraft-0003\nExperimentalRedstoneWireEvaluator\nO(N²) — Deque.contains() in BFS\nRedstone update (flag-gated)\nN=500 wires: ~O(250K) checks"
fillcolor="#fff8e8" color="#ddcc66" penwidth=1.0]
b4 [label="minecraft-0004\nMoveThroughVillageGoal\nO(N²) — linear scan in loop\nBounded N≤15\nVillager pathfinding"
fillcolor="#f8f8f8" color="#cccccc"]
b1 [label="minecraft-0001\nDependencySorter.isCyclic\nO(E^D) EXPONENTIAL\nDepth 14: 7,432 us/op\nDepth 16+: STACK OVERFLOW\nTrigger: world load, /reload"
penwidth=2.0]
b2 [label="minecraft-0002\nPistonStructureResolver\nO(P\u00b2) — bounded P<=12\nPiston activation"
penwidth=0.6]
b3 [label="minecraft-0003\nExperimentalRedstoneWireEvaluator\nO(N\u00b2) — Deque.contains() in BFS\nRedstone update (flag-gated)\nN=500 wires: ~O(250K) checks"
penwidth=1.2]
b4 [label="minecraft-0004\nMoveThroughVillageGoal\nO(N\u00b2) — linear scan in loop\nBounded N<=15\nVillager pathfinding"
penwidth=0.6]
}
// ── AFTER ────────────────────────────────────────────────
// ── AFTER — solid border marks fixed ─────────────────────
subgraph cluster_after {
label="AFTER (fixed — server-26.1-all-patched.jar)"
fontsize=9
color="#eeeeee"
bgcolor="#f5fff5"
penwidth=0.5
fontcolor="#448844"
color="black"
penwidth=1.2
fontcolor="black"
a1 [label="visited HashSet per call\nO(E) per call\nDepth 14: 67 µs/op\n110.9× faster\nDepth 16+: runs fine (linear)"
fillcolor="#e8f8e8" color="#55aa55" penwidth=1.4]
a2 [label="parallel HashSet<BlockPos>\nO(1) contains\n~1.1× (max 144 checks)"
fillcolor="#f5fff5" color="#aaccaa"]
a3 [label="companion HashSet<BlockPos>\nO(1) per enqueue check\nO(N) total BFS\n~N× speedup at scale"
fillcolor="#e8f8e8" color="#88cc88" penwidth=1.0]
a4 [label="companion HashSet<BlockPos>\nO(1) hasNotVisited\n~1.0× (max 15 entries)"
fillcolor="#f5fff5" color="#aaccaa"]
a1 [label="visited HashSet per call\nO(E) per call\nDepth 14: 67 us/op\n110.9x faster\nDepth 16+: runs fine (linear)"]
a2 [label="parallel HashSet<BlockPos>\nO(1) contains\n~1.1x (max 144 checks)"]
a3 [label="companion HashSet<BlockPos>\nO(1) per enqueue check\nO(N) total BFS\n~Nx speedup at scale"]
a4 [label="companion HashSet<BlockPos>\nO(1) hasNotVisited\n~1.0x (max 15 entries)"]
}
// ── Fix arrows ───────────────────────────────────────────
b1 -> a1 [label="110.9× at D=14\n(∞ at D=16+)" color="#cc3333" penwidth=1.8 fontcolor="#cc2222" fontsize=8]
b2 -> a2 [label="~1.1×" color="#cccccc" fontcolor="#aaaaaa" fontsize=8]
b3 -> a3 [label="~N× (N=wire count)" color="#cc9933" penwidth=1.0 fontcolor="#886622" fontsize=8]
b4 -> a4 [label="~1.0×" color="#cccccc" fontcolor="#aaaaaa" fontsize=8]
// ── Fix arrows — penwidth encodes speedup magnitude ───────
b1 -> a1 [label="110.9x at D=14\n(inf at D=16+)" penwidth=2.5 style=bold]
b2 -> a2 [label="~1.1x" penwidth=0.5]
b3 -> a3 [label="~Nx (N=wire count)" penwidth=1.2]
b4 -> a4 [label="~1.0x" penwidth=0.5]
{ rank=same; b1; a1 }
{ rank=same; b2; a2 }
{ rank=same; b3; a3 }
{ rank=same; b4; a4 }
// ── Severity legend ──────────────────────────────────────
// ── Severity legend — use shape instead of color ──────────
subgraph cluster_legend {
label="Severity"
label="Key: border thickness = severity"
fontsize=8
color="#eeeeee"
bgcolor="#fafafa"
penwidth=0.3
lexp [label="EXPONENTIAL — unbounded" shape=plaintext fontsize=8 fontcolor="#e05555"]
lmed [label="MEDIUM — flag-gated" shape=plaintext fontsize=8 fontcolor="#cc9933"]
llow [label="LOW — bounded, fixed for correctness" shape=plaintext fontsize=8 fontcolor="#aaaaaa"]
color="black"
penwidth=0.5
style=dotted
lexp [label="thick dashed = EXPONENTIAL/HIGH" shape=plaintext fontsize=8 fontcolor="black"]
llow [label="thin = LOW/bounded (fixed for correctness)" shape=plaintext fontsize=8 fontcolor="black"]
}
}

View file

@ -15,15 +15,15 @@ import os
OUT_DIR = os.path.join(os.path.dirname(__file__), "svg")
os.makedirs(OUT_DIR, exist_ok=True)
# ── Palette ──────────────────────────────────────────────────────────────────
BEFORE_COLOR = "#e8aaaa" # muted red — defective arc
AFTER_COLOR = "#aacbaa" # muted green — fixed arc
# ── Palette — print-friendly B&W (no color ink) ──────────────────────────────
BEFORE_COLOR = "#555555" # dark gray — defective arc (wasted time)
AFTER_COLOR = "#dddddd" # light gray — fixed arc (efficient portion)
GAP_COLOR = "white"
LABEL_COLOR = "#555555"
CENTER_TITLE = "#222222"
CENTER_SUB = "#888888"
LABEL_COLOR = "#000000"
CENTER_TITLE = "#000000"
CENTER_SUB = "#444444"
BG = "white"
RING_BG = "#f5f5f5" # empty ring background
RING_BG = "white" # no background fill — saves ink
# ── Geometry ─────────────────────────────────────────────────────────────────
CX, CY = 180, 180 # center
@ -117,9 +117,9 @@ def make_donut(title, subtitle, defects, peak_label, filename):
r_out = R_INNER_BASE + (n - i) * (RING_W + RING_GAP)
r_in = r_out - RING_W
# Background full ring
# Background full ring — outline only (white fill, thin gray stroke)
bg_path = arc_path(CX, CY, r_out, r_in, 0, 359.9)
lines.append(f' <path d="{bg_path}" fill="{RING_BG}"/>')
lines.append(f' <path d="{bg_path}" fill="{RING_BG}" stroke="#cccccc" stroke-width="0.5"/>')
# BEFORE arc — the whole 360° represents BEFORE time
# AFTER arc = 360° / speedup degrees (after is smaller)
@ -157,7 +157,7 @@ def make_donut(title, subtitle, defects, peak_label, filename):
lines.append(f' <text x="{lx_swatch + 14}" y="{ly_label + 11}" font-size="8.5" '
f'font-weight="500" fill="{CENTER_TITLE}">{name}</text>')
lines.append(f' <text x="{lx_swatch + 14}" y="{ly_label + 23}" font-size="8" '
f'fill="#cc6666">{annot}</text>')
f'fill="{CENTER_TITLE}" font-weight="600">{annot}</text>')
lines.append(f' <text x="{lx_swatch + 14}" y="{ly_label + 34}" font-size="7.5" '
f'fill="{CENTER_SUB}">before arc = {before_deg/3.6:.0f}% of time</text>')
@ -167,11 +167,11 @@ def make_donut(title, subtitle, defects, peak_label, filename):
# Bottom legend
lines.append(f' <rect x="20" y="{SVG_H-28}" width="12" height="12" fill="{BEFORE_COLOR}" rx="2"/>')
lines.append(f' <text x="36" y="{SVG_H-19}" font-size="8" fill="{CENTER_SUB}">BEFORE — wasted time</text>')
lines.append(f' <rect x="160" y="{SVG_H-28}" width="12" height="12" fill="{AFTER_COLOR}" rx="2"/>')
lines.append(f' <text x="176" y="{SVG_H-19}" font-size="8" fill="{CENTER_SUB}">AFTER — time with fix</text>')
lines.append(f' <text x="310" y="{SVG_H-19}" font-size="7.5" fill="{CENTER_SUB}">'
f'Arc ∝ fraction of BEFORE time. Green = fixed portion.</text>')
lines.append(f' <text x="36" y="{SVG_H-19}" font-size="8" fill="{CENTER_SUB}">BEFORE — wasted time (dark)</text>')
lines.append(f' <rect x="180" y="{SVG_H-28}" width="12" height="12" fill="{AFTER_COLOR}" stroke="#999" stroke-width="0.5" rx="2"/>')
lines.append(f' <text x="196" y="{SVG_H-19}" font-size="8" fill="{CENTER_SUB}">AFTER — time with fix (light)</text>')
lines.append(f' <text x="350" y="{SVG_H-19}" font-size="7.5" fill="{CENTER_SUB}">'
f'Arc proportional to fraction of BEFORE time.</text>')
lines.append('</svg>')

View file

@ -1,169 +1,195 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 260" width="760" height="260">
<rect width="760" height="260" fill="white"/>
<!-- Title -->
<text x="380" y="14" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="10.5" fill="#333">BenchMax — Speedup Grows With Scale · Three Ecosystems · Algorithmic complexity fix only</text>
<!-- ── Panel 1: javac Tarjan ─────────────────────────────────────────────── -->
<rect x="6" y="20" width="238" height="218" rx="3" fill="#f8faff" stroke="#c8d8f0" stroke-width="0.6"/>
<text x="125" y="35" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="9" fill="#334488" font-weight="bold">javac-0001 Tarjan starWithBackEdges(V)</text>
<text x="125" y="47" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#666">GraphUtils.findAllCycles — visited set fix</text>
<!-- Column headers -->
<text x="30" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Nodes V</text>
<text x="100" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#cc4444">Before (ms)</text>
<text x="165" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#336633">After (ms)</text>
<text x="215" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#336633">Speed</text>
<line x1="14" y1="65" x2="236" y2="65" stroke="#ddd" stroke-width="0.4"/>
<!-- Data rows: V, before_ms, after_ms, speedup -->
<!-- V=200: 2.87× -->
<text x="30" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">200</text>
<text x="100" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="165" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="215" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">2.9×</text>
<text x="30" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">400</text>
<text x="100" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="165" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="215" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">3.9×</text>
<text x="30" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">800</text>
<text x="100" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="165" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="215" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">5.5×</text>
<text x="30" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">2,000</text>
<text x="100" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="165" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="215" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">~12×</text>
<text x="30" y="143" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">3,200</text>
<text x="100" y="143" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="165" y="143" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="215" y="143" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">~23×</text>
<rect x="14" y="154" width="224" height="22" rx="2" fill="#e6f0ff" stroke="#aac8ee" stroke-width="0.6"/>
<text x="126" y="169" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8.5" fill="#224488">Grows as O(V²) → O(V log V)</text>
<!-- Spark bar chart (visual speedup) -->
<text x="14" y="192" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">Speedup at scale (V=200→3200):</text>
<!-- bars: max speedup ~23× → bar_w = 23/23 * 180 = 180 -->
<rect x="14" y="196" width="23" height="10" rx="1" fill="#aaccee"/> <!-- 2.9/23*180=23 -->
<rect x="14" y="208" width="31" height="10" rx="1" fill="#88aadd"/> <!-- 3.9/23*180=30 -->
<rect x="14" y="220" width="43" height="10" rx="1" fill="#6699cc"/>
<rect x="14" y="232" width="94" height="10" rx="1" fill="#4477bb"/>
<rect x="14" y="244" width="180" height="10" rx="1" fill="#225599"/>
<text x="200" y="205" font-family="Helvetica,sans-serif" font-size="7" fill="#333">2.9×</text>
<text x="200" y="217" font-family="Helvetica,sans-serif" font-size="7" fill="#333">3.9×</text>
<text x="200" y="229" font-family="Helvetica,sans-serif" font-size="7" fill="#333">5.5×</text>
<text x="200" y="241" font-family="Helvetica,sans-serif" font-size="7" fill="#333">~12×</text>
<text x="200" y="253" font-family="Helvetica,sans-serif" font-size="7" fill="#333">~23×</text>
<!-- ── Panel 2: minecraft-0001 ───────────────────────────────────────────── -->
<rect x="254" y="20" width="248" height="218" rx="3" fill="#fff8f8" stroke="#f0c8c8" stroke-width="0.6"/>
<text x="378" y="35" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="9" fill="#884444" font-weight="bold">minecraft-0001 DependencySorter diamond D</text>
<text x="378" y="47" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#666">isCyclic visited-set fix · real server + microbench</text>
<text x="275" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Depth D</text>
<text x="330" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#cc4444">Before</text>
<text x="395" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#336633">After</text>
<text x="455" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#336633">Speed</text>
<line x1="262" y1="65" x2="494" y2="65" stroke="#ddd" stroke-width="0.4"/>
<text x="275" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">8</text>
<text x="330" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="395" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="455" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">4×</text>
<text x="275" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">10</text>
<text x="330" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="395" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="455" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">11.7×</text>
<text x="275" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">12</text>
<text x="330" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="395" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="455" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">31.5×</text>
<text x="275" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">14</text>
<text x="330" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444">7,432 µs</text>
<text x="395" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633">67 µs</text>
<text x="455" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">110.9×</text>
<!-- D=16 real server — highlight row -->
<rect x="262" y="133" width="232" height="16" rx="1" fill="#fff0f0"/>
<text x="275" y="145" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">16 ← real</text>
<text x="330" y="145" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc3333">19,255 ms</text>
<text x="395" y="145" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633">3,087 ms</text>
<text x="455" y="145" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">6.2×</text>
<text x="275" y="163" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc2222">16+ (vanilla)</text>
<text x="330" y="163" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc2222">StackOverflow</text>
<text x="395" y="163" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633">stable</text>
<text x="455" y="163" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">∞ eff.</text>
<rect x="262" y="172" width="232" height="22" rx="2" fill="#ffe6e6" stroke="#e88888" stroke-width="0.6"/>
<text x="378" y="187" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8.5" fill="#882222">O(E^D) exponential → O(E·D) linear</text>
<!-- Spark bars -->
<text x="262" y="208" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">Speedup at scale (D=8→16):</text>
<rect x="262" y="212" width="6" height="10" rx="1" fill="#ffcccc"/> <!-- 4× -->
<rect x="262" y="224" width="19" height="10" rx="1" fill="#ffaaaa"/> <!-- 11.7× -->
<rect x="262" y="236" width="52" height="10" rx="1" fill="#ff8888"/> <!-- 31.5× -->
<rect x="262" y="248" width="180" height="10" rx="1" fill="#ee4444"/> <!-- 110.9× -->
<text x="448" y="221" font-family="Helvetica,sans-serif" font-size="7" fill="#333">4×</text>
<text x="448" y="233" font-family="Helvetica,sans-serif" font-size="7" fill="#333">11.7×</text>
<text x="448" y="245" font-family="Helvetica,sans-serif" font-size="7" fill="#333">31.5×</text>
<text x="448" y="257" font-family="Helvetica,sans-serif" font-size="7" fill="#333">110.9× (µbench D=14)</text>
<!-- ── Panel 3: create-0001 ──────────────────────────────────────────────── -->
<rect x="512" y="20" width="242" height="218" rx="3" fill="#fdf8f8" stroke="#e8d8d8" stroke-width="0.6"/>
<text x="633" y="35" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="9" fill="#775544" font-weight="bold">create-0001 TrackGraph BFS ArrayList→Queue</text>
<text x="633" y="47" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#666">remove(0) O(n) dequeue → ArrayDeque O(1)</text>
<text x="530" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Nodes V</text>
<text x="588" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#cc4444">Before</text>
<text x="645" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#336633">After</text>
<text x="700" y="62" font-family="Helvetica,sans-serif" font-size="8" fill="#336633">Speed</text>
<line x1="520" y1="65" x2="746" y2="65" stroke="#ddd" stroke-width="0.4"/>
<text x="530" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">100</text>
<text x="588" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="645" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="700" y="79" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">~1.5×</text>
<text x="530" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">500</text>
<text x="588" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="645" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="700" y="95" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">~6×</text>
<text x="530" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">2,000</text>
<text x="588" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="645" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="700" y="111" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">~25×</text>
<text x="530" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">5,000</text>
<text x="588" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc4444"></text>
<text x="645" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633"></text>
<text x="700" y="127" font-family="Helvetica,sans-serif" font-size="8.5" fill="#226622" font-weight="bold">~60×</text>
<rect x="520" y="136" width="226" height="22" rx="2" fill="#fdeee8" stroke="#ddaa88" stroke-width="0.6"/>
<text x="633" y="151" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8.5" fill="#664422">O(V²) dequeue → O(V) BFS ⚠ upstream open</text>
<text x="520" y="175" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Note: defect open in Create mod (upstream).</text>
<text x="520" y="187" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Triggered by large rail networks (&gt;500 nodes).</text>
<text x="520" y="199" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Fix: replace ArrayList with ArrayDeque.</text>
<!-- Spark bars -->
<text x="520" y="215" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">Speedup at scale (V=100→5000):</text>
<rect x="520" y="219" width="5" height="10" rx="1" fill="#e8cccc"/>
<rect x="520" y="231" width="18" height="10" rx="1" fill="#ddaaaa"/>
<rect x="520" y="243" width="75" height="10" rx="1" fill="#cc8888"/>
<rect x="520" y="255" width="180" height="10" rx="1" fill="#bb5555"/>
<text x="706" y="228" font-family="Helvetica,sans-serif" font-size="7" fill="#333">~1.5×</text>
<text x="706" y="240" font-family="Helvetica,sans-serif" font-size="7" fill="#333">~6×</text>
<text x="706" y="252" font-family="Helvetica,sans-serif" font-size="7" fill="#333">~25×</text>
<text x="706" y="264" font-family="Helvetica,sans-serif" font-size="7" fill="#333">~60×</text>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: benchmax Pages: 1 -->
<svg width="813pt" height="529pt"
viewBox="0.00 0.00 813.20 529.20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(21.6 507.6)">
<title>benchmax</title>
<polygon fill="white" stroke="transparent" points="-21.6,21.6 -21.6,-507.6 791.6,-507.6 791.6,21.6 -21.6,21.6"/>
<text text-anchor="middle" x="122.5" y="-473.2" font-family="Helvetica,sans-Serif" font-size="11.00">BenchMax — Scaling Curves at Extremes</text>
<g id="clust1" class="cluster">
<title>cluster_javac</title>
<polygon fill="white" stroke="black" stroke-width="0.8" points="8,-330 8,-458 570.5,-458 570.5,-330 8,-330"/>
<text text-anchor="middle" x="96" y="-446.8" font-family="Helvetica,sans-Serif" font-size="9.00">javac Tarjan &#160;starWithBackEdges(V)</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_mc</title>
<polygon fill="white" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" points="109.5,-158 109.5,-322 762,-322 762,-158 109.5,-158"/>
<text text-anchor="middle" x="196" y="-310.8" font-family="Helvetica,sans-Serif" font-size="9.00">minecraft&#45;0001 &#160;diamond depth D</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_create</title>
<polygon fill="white" stroke="black" stroke-width="0.8" points="222,-8 222,-150 751,-150 751,-8 222,-8"/>
<text text-anchor="middle" x="345" y="-138.8" font-family="Helvetica,sans-Serif" font-size="9.00">create&#45;0001 &#160;TrackGraph BFS &#160;ArrayList.remove(0)</text>
</g>
<!-- jv200 -->
<g id="node1" class="node">
<title>jv200</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="36" cy="-370" rx="20" ry="20"/>
<text text-anchor="middle" x="36" y="-372.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=200</text>
<text text-anchor="middle" x="36" y="-363.6" font-family="Helvetica,sans-Serif" font-size="8.00">2.87x</text>
</g>
<!-- jv400 -->
<g id="node2" class="node">
<title>jv400</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="137.5" cy="-370" rx="23.5" ry="23.5"/>
<text text-anchor="middle" x="137.5" y="-372.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=400</text>
<text text-anchor="middle" x="137.5" y="-363.6" font-family="Helvetica,sans-Serif" font-size="8.00">3.87x</text>
</g>
<!-- jv200&#45;&gt;jv400 -->
<g id="edge1" class="edge">
<title>jv200&#45;&gt;jv400</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M55.49,-374.72C68.97,-377.29 79.83,-376.83 109.72,-373.35"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="110.06,-374.72 113.87,-372.87 109.73,-371.94 110.06,-374.72"/>
</g>
<!-- jv800 -->
<g id="node3" class="node">
<title>jv800</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="248" cy="-370" rx="29" ry="29"/>
<text text-anchor="middle" x="248" y="-372.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=800</text>
<text text-anchor="middle" x="248" y="-363.6" font-family="Helvetica,sans-Serif" font-size="8.00">5.47x</text>
</g>
<!-- jv400&#45;&gt;jv800 -->
<g id="edge2" class="edge">
<title>jv400&#45;&gt;jv800</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M160.18,-377.21C174.78,-380.88 186.24,-380.35 215.22,-375.63"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="215.51,-377 219.23,-374.97 215.06,-374.24 215.51,-377"/>
</g>
<!-- jv2000 -->
<g id="node4" class="node">
<title>jv2000</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="371" cy="-379" rx="36" ry="36"/>
<text text-anchor="middle" x="371" y="-381.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=2000</text>
<text text-anchor="middle" x="371" y="-372.6" font-family="Helvetica,sans-Serif" font-size="8.00">~12x</text>
</g>
<!-- jv800&#45;&gt;jv2000 -->
<g id="edge3" class="edge">
<title>jv800&#45;&gt;jv2000</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M274.07,-383.2C293.52,-392.03 305.28,-393.04 331.76,-387.85"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="332.13,-389.2 335.78,-387.04 331.58,-386.46 332.13,-389.2"/>
</g>
<!-- md12 -->
<g id="node8" class="node">
<title>md12</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="371" cy="-231" rx="36" ry="36"/>
<text text-anchor="middle" x="371" y="-233.6" font-family="Helvetica,sans-Serif" font-size="8.00">D=12</text>
<text text-anchor="middle" x="371" y="-224.6" font-family="Helvetica,sans-Serif" font-size="8.00">31.5x</text>
</g>
<!-- jv800&#45;&gt;md12 -->
<!-- jv5000 -->
<g id="node5" class="node">
<title>jv5000</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="515.5" cy="-385" rx="47" ry="47"/>
<text text-anchor="middle" x="515.5" y="-387.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=5000</text>
<text text-anchor="middle" x="515.5" y="-378.6" font-family="Helvetica,sans-Serif" font-size="8.00">~30x</text>
</g>
<!-- jv2000&#45;&gt;jv5000 -->
<g id="edge4" class="edge">
<title>jv2000&#45;&gt;jv5000</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M405,-391.11C434.26,-401.11 449.33,-404.22 466.98,-401.12"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="467.39,-402.46 471.04,-400.31 466.84,-399.72 467.39,-402.46"/>
</g>
<!-- md8 -->
<g id="node6" class="node">
<title>md8</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="137.5" cy="-231" rx="20" ry="20"/>
<text text-anchor="middle" x="137.5" y="-233.6" font-family="Helvetica,sans-Serif" font-size="8.00">D=8</text>
<text text-anchor="middle" x="137.5" y="-224.6" font-family="Helvetica,sans-Serif" font-size="8.00">4x</text>
</g>
<!-- md10 -->
<g id="node7" class="node">
<title>md10</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="248" cy="-231" rx="27" ry="27"/>
<text text-anchor="middle" x="248" y="-233.6" font-family="Helvetica,sans-Serif" font-size="8.00">D=10</text>
<text text-anchor="middle" x="248" y="-224.6" font-family="Helvetica,sans-Serif" font-size="8.00">11.7x</text>
</g>
<!-- md8&#45;&gt;md10 -->
<g id="edge5" class="edge">
<title>md8&#45;&gt;md10</title>
<path fill="none" stroke="black" stroke-width="1.5" d="M157.6,-230.87C171.61,-230.8 183.51,-230.81 216.66,-230.91"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="216.8,-232.31 220.81,-230.92 216.81,-229.51 216.8,-232.31"/>
</g>
<!-- md10&#45;&gt;md12 -->
<g id="edge6" class="edge">
<title>md10&#45;&gt;md12</title>
<path fill="none" stroke="black" stroke-width="1.5" d="M275.24,-230.58C288.26,-230.46 301.56,-230.5 330.86,-230.7"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="330.9,-232.1 334.91,-230.73 330.92,-229.3 330.9,-232.1"/>
</g>
<!-- md14 -->
<g id="node9" class="node">
<title>md14</title>
<ellipse fill="white" stroke="black" stroke-width="2" cx="515.5" cy="-231" rx="50.5" ry="50.5"/>
<text text-anchor="middle" x="515.5" y="-233.6" font-family="Helvetica,sans-Serif" font-size="8.00">D=14</text>
<text text-anchor="middle" x="515.5" y="-224.6" font-family="Helvetica,sans-Serif" font-size="8.00">88x</text>
</g>
<!-- md12&#45;&gt;md14 -->
<g id="edge7" class="edge">
<title>md12&#45;&gt;md14</title>
<path fill="none" stroke="black" stroke-width="1.5" d="M407.18,-230.65C431.87,-230.42 448.02,-230.29 460.53,-230.26"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="460.65,-231.66 464.65,-230.26 460.64,-228.86 460.65,-231.66"/>
</g>
<!-- cv2000 -->
<g id="node13" class="node">
<title>cv2000</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="515.5" cy="-77" rx="39.5" ry="39.5"/>
<text text-anchor="middle" x="515.5" y="-79.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=2000</text>
<text text-anchor="middle" x="515.5" y="-70.6" font-family="Helvetica,sans-Serif" font-size="8.00">~25x</text>
</g>
<!-- md12&#45;&gt;cv2000 -->
<!-- md16 -->
<g id="node10" class="node">
<title>md16</title>
<ellipse fill="white" stroke="black" stroke-width="2.5" stroke-dasharray="5,2" cx="689" cy="-231" rx="65" ry="65"/>
<text text-anchor="middle" x="689" y="-233.6" font-family="Helvetica,sans-Serif" font-size="8.00">D=16</text>
<text text-anchor="middle" x="689" y="-224.6" font-family="Helvetica,sans-Serif" font-size="8.00">OVERFLOW</text>
</g>
<!-- md14&#45;&gt;md16 -->
<g id="edge8" class="edge">
<title>md14&#45;&gt;md16</title>
<path fill="none" stroke="black" stroke-width="1.5" d="M566.23,-230.87C589.98,-230.81 606.68,-230.77 619.95,-230.76"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="619.96,-232.16 623.96,-230.76 619.96,-229.36 619.96,-232.16"/>
</g>
<!-- cv100 -->
<g id="node11" class="node">
<title>cv100</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="248" cy="-77" rx="18" ry="18"/>
<text text-anchor="middle" x="248" y="-79.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=100</text>
<text text-anchor="middle" x="248" y="-70.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.5x</text>
</g>
<!-- cv500 -->
<g id="node12" class="node">
<title>cv500</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="371" cy="-77" rx="25" ry="25"/>
<text text-anchor="middle" x="371" y="-79.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=500</text>
<text text-anchor="middle" x="371" y="-70.6" font-family="Helvetica,sans-Serif" font-size="8.00">~6x</text>
</g>
<!-- cv100&#45;&gt;cv500 -->
<g id="edge9" class="edge">
<title>cv100&#45;&gt;cv500</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M264.9,-69.73C293.8,-57.74 304.23,-57.3 342.52,-68.4"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="342.59,-69.88 346.82,-69.66 343.37,-67.19 342.59,-69.88"/>
</g>
<!-- cv500&#45;&gt;cv2000 -->
<g id="edge10" class="edge">
<title>cv500&#45;&gt;cv2000</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M394.87,-69.21C435.48,-56.2 451.04,-53.33 474.71,-60.61"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="474.35,-61.97 478.58,-61.87 475.21,-59.31 474.35,-61.97"/>
</g>
<!-- cv5000 -->
<g id="node14" class="node">
<title>cv5000</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="689" cy="-70" rx="54" ry="54"/>
<text text-anchor="middle" x="689" y="-72.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=5000</text>
<text text-anchor="middle" x="689" y="-63.6" font-family="Helvetica,sans-Serif" font-size="8.00">~60x</text>
</g>
<!-- cv2000&#45;&gt;cv5000 -->
<g id="edge11" class="edge">
<title>cv2000&#45;&gt;cv5000</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M554.27,-68.94C593.38,-60.95 614.31,-57.51 632.16,-58.02"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="632.11,-59.42 636.16,-58.2 632.23,-56.62 632.11,-59.42"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

@ -11,18 +11,18 @@
<polygon fill="white" stroke="transparent" points="-21.6,21.6 -21.6,-303.6 580.6,-303.6 580.6,21.6 -21.6,21.6"/>
<g id="clust1" class="cluster">
<title>cluster_before</title>
<polygon fill="#fffafa" stroke="#f5dddd" stroke-width="0.4" points="8,-184 8,-274 537,-274 537,-184 8,-184"/>
<text text-anchor="middle" x="272.5" y="-262" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#cc4444">BEFORE</text>
<polygon fill="white" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" points="8,-184 8,-274 537,-274 537,-184 8,-184"/>
<text text-anchor="middle" x="272.5" y="-262" font-family="Helvetica,sans-Serif" font-size="10.00">BEFORE</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_after</title>
<polygon fill="#f8fdf8" stroke="#ddeedd" stroke-width="0.4" points="16,-79 16,-151 551,-151 551,-79 16,-79"/>
<text text-anchor="middle" x="283.5" y="-139" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#338833">AFTER</text>
<polygon fill="white" stroke="black" stroke-width="1.5" points="16,-79 16,-151 551,-151 551,-79 16,-79"/>
<text text-anchor="middle" x="283.5" y="-139" font-family="Helvetica,sans-Serif" font-size="10.00">AFTER</text>
</g>
<!-- b_exp -->
<g id="node1" class="node">
<title>b_exp</title>
<polygon fill="#fce8e8" stroke="#e88888" stroke-width="0.4" points="115.5,-238 16.5,-238 16.5,-201 115.5,-201 115.5,-238"/>
<polygon fill="white" stroke="black" stroke-width="2.5" points="115.5,-238 16.5,-238 16.5,-201 115.5,-201 115.5,-238"/>
<text text-anchor="middle" x="66" y="-226.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(E^D)</text>
<text text-anchor="middle" x="66" y="-217.6" font-family="Helvetica,sans-Serif" font-size="8.00">exponential</text>
<text text-anchor="middle" x="66" y="-208.6" font-family="Helvetica,sans-Serif" font-size="8.00">DependencySorter</text>
@ -30,7 +30,7 @@
<!-- a_lin -->
<g id="node5" class="node">
<title>a_lin</title>
<polygon fill="#e8f5e8" stroke="#88cc88" stroke-width="0.4" points="109.5,-124 24.5,-124 24.5,-87 109.5,-87 109.5,-124"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="109.5,-124 24.5,-124 24.5,-87 109.5,-87 109.5,-124"/>
<text text-anchor="middle" x="67" y="-112.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(E)</text>
<text text-anchor="middle" x="67" y="-103.6" font-family="Helvetica,sans-Serif" font-size="8.00">per isCyclic call</text>
<text text-anchor="middle" x="67" y="-94.6" font-family="Helvetica,sans-Serif" font-size="8.00">visited set</text>
@ -38,21 +38,21 @@
<!-- b_exp&#45;&gt;a_lin -->
<g id="edge1" class="edge">
<title>b_exp&#45;&gt;a_lin</title>
<path fill="none" stroke="#88cc88" d="M67,-200.93C67,-200.93 67,-128.06 67,-128.06"/>
<polygon fill="#88cc88" stroke="#88cc88" points="68.4,-128.06 67,-124.06 65.6,-128.06 68.4,-128.06"/>
<text text-anchor="middle" x="94.5" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#999999">add visited set</text>
<path fill="none" stroke="black" stroke-width="2" d="M67,-200.93C67,-200.93 67,-128.06 67,-128.06"/>
<polygon fill="black" stroke="black" stroke-width="2" points="68.4,-128.06 67,-124.06 65.6,-128.06 68.4,-128.06"/>
<text text-anchor="middle" x="94.5" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00">add visited set</text>
</g>
<!-- b_cub -->
<g id="node2" class="node">
<title>b_cub</title>
<polygon fill="#fde8d8" stroke="#e8a888" stroke-width="0.4" points="251.5,-237.5 158.5,-237.5 158.5,-201.5 251.5,-201.5 251.5,-237.5"/>
<polygon fill="white" stroke="black" stroke-width="2" points="251.5,-237.5 158.5,-237.5 158.5,-201.5 251.5,-201.5 251.5,-237.5"/>
<text text-anchor="middle" x="205" y="-222.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(n³)</text>
<text text-anchor="middle" x="205" y="-213.1" font-family="Helvetica,sans-Serif" font-size="8.00">scala3 constraint</text>
</g>
<!-- a_quad2 -->
<g id="node6" class="node">
<title>a_quad2</title>
<polygon fill="#eef5e8" stroke="#aacc88" stroke-width="0.4" points="255,-124 153,-124 153,-87 255,-87 255,-124"/>
<polygon fill="white" stroke="black" stroke-width="0.8" stroke-dasharray="5,2" points="255,-124 153,-124 153,-87 255,-87 255,-124"/>
<text text-anchor="middle" x="204" y="-112.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(n²)</text>
<text text-anchor="middle" x="204" y="-103.6" font-family="Helvetica,sans-Serif" font-size="8.00">scala3 still complex</text>
<text text-anchor="middle" x="204" y="-94.6" font-family="Helvetica,sans-Serif" font-size="8.00">but inner loop O(1)</text>
@ -60,14 +60,14 @@
<!-- b_cub&#45;&gt;a_quad2 -->
<g id="edge2" class="edge">
<title>b_cub&#45;&gt;a_quad2</title>
<path fill="none" stroke="#aacc88" stroke-width="0.8" d="M205,-201.44C205,-201.44 205,-128.24 205,-128.24"/>
<polygon fill="#aacc88" stroke="#aacc88" stroke-width="0.8" points="206.4,-128.24 205,-124.24 203.6,-128.24 206.4,-128.24"/>
<text text-anchor="middle" x="222.5" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#999999">inner O(1)</text>
<path fill="none" stroke="black" stroke-width="1.2" d="M205,-201.44C205,-201.44 205,-128.24 205,-128.24"/>
<polygon fill="black" stroke="black" stroke-width="1.2" points="206.4,-128.24 205,-124.24 203.6,-128.24 206.4,-128.24"/>
<text text-anchor="middle" x="222.5" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00">inner O(1)</text>
</g>
<!-- b_quad -->
<g id="node3" class="node">
<title>b_quad</title>
<polygon fill="#fef0e0" stroke="#e8cc88" stroke-width="0.4" points="393.5,-247 294.5,-247 294.5,-192 393.5,-192 393.5,-247"/>
<polygon fill="white" stroke="black" stroke-width="1.5" points="393.5,-247 294.5,-247 294.5,-192 393.5,-192 393.5,-247"/>
<text text-anchor="middle" x="344" y="-235.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(n²)</text>
<text text-anchor="middle" x="344" y="-226.6" font-family="Helvetica,sans-Serif" font-size="8.00">javac Tarjan</text>
<text text-anchor="middle" x="344" y="-217.6" font-family="Helvetica,sans-Serif" font-size="8.00">TypeScript checker</text>
@ -77,7 +77,7 @@
<!-- a_lin2 -->
<g id="node7" class="node">
<title>a_lin2</title>
<polygon fill="#e8f5e8" stroke="#88cc88" stroke-width="0.4" points="386,-124 298,-124 298,-87 386,-87 386,-124"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="386,-124 298,-124 298,-87 386,-87 386,-124"/>
<text text-anchor="middle" x="342" y="-112.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(V+E)</text>
<text text-anchor="middle" x="342" y="-103.6" font-family="Helvetica,sans-Serif" font-size="8.00">Tarjan fixed</text>
<text text-anchor="middle" x="342" y="-94.6" font-family="Helvetica,sans-Serif" font-size="8.00">ArrayDeque BFS</text>
@ -85,14 +85,14 @@
<!-- b_quad&#45;&gt;a_lin2 -->
<g id="edge3" class="edge">
<title>b_quad&#45;&gt;a_lin2</title>
<path fill="none" stroke="#88cc88" d="M342,-191.9C342,-191.9 342,-128.29 342,-128.29"/>
<polygon fill="#88cc88" stroke="#88cc88" points="343.4,-128.29 342,-124.29 340.6,-128.29 343.4,-128.29"/>
<text text-anchor="middle" x="374" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#999999">Set / ArrayDeque</text>
<path fill="none" stroke="black" stroke-width="2" d="M342,-191.9C342,-191.9 342,-128.29 342,-128.29"/>
<polygon fill="black" stroke="black" stroke-width="2" points="343.4,-128.29 342,-124.29 340.6,-128.29 343.4,-128.29"/>
<text text-anchor="middle" x="374" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00">Set / ArrayDeque</text>
</g>
<!-- b_med -->
<g id="node4" class="node">
<title>b_med</title>
<polygon fill="#f8f8e8" stroke="#cccc88" stroke-width="0.4" points="529,-238 437,-238 437,-201 529,-201 529,-238"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="529,-238 437,-238 437,-201 529,-201 529,-238"/>
<text text-anchor="middle" x="483" y="-226.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(n·k)</text>
<text text-anchor="middle" x="483" y="-217.6" font-family="Helvetica,sans-Serif" font-size="8.00">bounded defects</text>
<text text-anchor="middle" x="483" y="-208.6" font-family="Helvetica,sans-Serif" font-size="8.00">cpython, gcc...</text>
@ -100,46 +100,46 @@
<!-- a_lin3 -->
<g id="node8" class="node">
<title>a_lin3</title>
<polygon fill="#f0f5e8" stroke="#aabb88" stroke-width="0.4" points="543,-123.5 429,-123.5 429,-87.5 543,-87.5 543,-123.5"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="543,-123.5 429,-123.5 429,-87.5 543,-87.5 543,-123.5"/>
<text text-anchor="middle" x="486" y="-108.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(n)</text>
<text text-anchor="middle" x="486" y="-99.1" font-family="Helvetica,sans-Serif" font-size="8.00">bounded + O(1) check</text>
</g>
<!-- b_med&#45;&gt;a_lin3 -->
<g id="edge4" class="edge">
<title>b_med&#45;&gt;a_lin3</title>
<path fill="none" stroke="#aabb88" stroke-width="0.8" d="M483,-200.93C483,-200.93 483,-127.68 483,-127.68"/>
<polygon fill="#aabb88" stroke="#aabb88" stroke-width="0.8" points="484.4,-127.68 483,-123.68 481.6,-127.68 484.4,-127.68"/>
<text text-anchor="middle" x="499.5" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#999999">HashSet</text>
<path fill="none" stroke="black" stroke-width="1.2" d="M483,-200.93C483,-200.93 483,-127.68 483,-127.68"/>
<polygon fill="black" stroke="black" stroke-width="1.2" points="484.4,-127.68 483,-123.68 481.6,-127.68 484.4,-127.68"/>
<text text-anchor="middle" x="499.5" y="-161.4" font-family="Helvetica,sans-Serif" font-size="7.00">HashSet</text>
</g>
<!-- s1 -->
<g id="node9" class="node">
<title>s1</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="110.5,-36 23.5,-36 23.5,0 110.5,0 110.5,-36"/>
<text text-anchor="middle" x="67" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#cc4444">88x at depth 14</text>
<text text-anchor="middle" x="67" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#cc4444"> at depth 16</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="116,-36 18,-36 18,0 116,0 116,-36"/>
<text text-anchor="middle" x="67" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00">88x at depth 14</text>
<text text-anchor="middle" x="67" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00">u221e at depth 16</text>
</g>
<!-- a_lin&#45;&gt;s1 -->
<!-- s2 -->
<g id="node10" class="node">
<title>s2</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="239,-36 163,-36 163,0 239,0 239,-36"/>
<text text-anchor="middle" x="201" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#888888">— (still O(n²))</text>
<text text-anchor="middle" x="201" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#888888">but bounded</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="239,-36 163,-36 163,0 239,0 239,-36"/>
<text text-anchor="middle" x="201" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00">— (still O(n²))</text>
<text text-anchor="middle" x="201" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00">but bounded</text>
</g>
<!-- a_quad2&#45;&gt;s2 -->
<!-- s3 -->
<g id="node11" class="node">
<title>s3</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="405.5,-36 282.5,-36 282.5,0 405.5,0 405.5,-36"/>
<text text-anchor="middle" x="344" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#338833">23x at V=800</text>
<text text-anchor="middle" x="344" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#338833">401x fewer comparisons</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="405.5,-36 282.5,-36 282.5,0 405.5,0 405.5,-36"/>
<text text-anchor="middle" x="344" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00">23x at V=800</text>
<text text-anchor="middle" x="344" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00">401x fewer comparisons</text>
</g>
<!-- a_lin2&#45;&gt;s3 -->
<!-- s4 -->
<g id="node12" class="node">
<title>s4</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="521.5,-36 450.5,-36 450.5,0 521.5,0 521.5,-36"/>
<text text-anchor="middle" x="486" y="-16.1" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#888888">24x typical</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="521.5,-36 450.5,-36 450.5,0 521.5,0 521.5,-36"/>
<text text-anchor="middle" x="486" y="-16.1" font-family="Helvetica,sans-Serif" font-size="8.00">24x typical</text>
</g>
<!-- a_lin3&#45;&gt;s4 -->
</g>

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Before After
Before After

View file

@ -1,155 +1,246 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 300" width="760" height="300">
<rect width="760" height="300" fill="white"/>
<!-- Title -->
<text x="380" y="14" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="10.5" fill="#333333">CWE-407: O(n²+) Unvisited Graph Traversal · 25 confirmed defects · 8 ecosystems</text>
<!-- Row bands (severity lanes) -->
<rect x="1" y="20" width="758" height="46" rx="2" fill="#fffafa" stroke="#f5dddd" stroke-width="0.6"/>
<rect x="1" y="68" width="758" height="46" rx="2" fill="#fffcf5" stroke="#f5ead5" stroke-width="0.6"/>
<rect x="1" y="116" width="758" height="84" rx="2" fill="#f8fdf8" stroke="#ddeedd" stroke-width="0.6"/>
<rect x="1" y="202" width="758" height="46" rx="2" fill="#fafafa" stroke="#e8e8f0" stroke-width="0.6"/>
<rect x="1" y="250" width="758" height="48" rx="2" fill="#fefefe" stroke="#eeeeee" stroke-width="0.6"/>
<!-- Severity labels (left column) -->
<text x="6" y="36" font-family="Helvetica,sans-serif" font-size="8" fill="#cc4444" font-weight="bold">EXPONENTIAL</text>
<text x="6" y="48" font-family="Helvetica,sans-serif" font-size="7.5" fill="#cc4444">O(E^D)</text>
<text x="6" y="84" font-family="Helvetica,sans-serif" font-size="8" fill="#cc6600" font-weight="bold">CRITICAL</text>
<text x="6" y="96" font-family="Helvetica,sans-serif" font-size="7.5" fill="#cc6600">O(n³)</text>
<text x="6" y="150" font-family="Helvetica,sans-serif" font-size="8" fill="#558855" font-weight="bold">HIGH</text>
<text x="6" y="162" font-family="Helvetica,sans-serif" font-size="7.5" fill="#558855">O(n²)</text>
<text x="6" y="218" font-family="Helvetica,sans-serif" font-size="8" fill="#666688" font-weight="bold">MEDIUM</text>
<text x="6" y="230" font-family="Helvetica,sans-serif" font-size="7.5" fill="#666688">O(n log n)</text>
<text x="6" y="266" font-family="Helvetica,sans-serif" font-size="8" fill="#999999" font-weight="bold">LOW</text>
<text x="6" y="278" font-family="Helvetica,sans-serif" font-size="7.5" fill="#999999">bounded</text>
<!-- Divider -->
<line x1="107" y1="20" x2="107" y2="298" stroke="#cccccc" stroke-width="0.5"/>
<!-- ── EXPONENTIAL chips ─────────────────────────────────────────────── -->
<!-- minecraft-0001: wide chip with real benchmark -->
<rect x="112" y="26" width="155" height="34" rx="3" fill="#fce8e8" stroke="#e05555" stroke-width="1.4"/>
<text x="189" y="39" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">minecraft-0001</text>
<text x="189" y="52" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#e05555">DependencySorter.isCyclic · O(E^D)</text>
<text x="276" y="37" font-family="Helvetica,sans-serif" font-size="8.5" fill="#222">/reload: 19,255 ms → 3,087 ms (6.2× speedup)</text>
<text x="276" y="52" font-family="Helvetica,sans-serif" font-size="7.5" fill="#777">Affects: Vanilla · Paper · Spigot · Purpur · Forge · NeoForge · Fabric · Quilt</text>
<!-- ── CRITICAL chips ──────────────────────────────────────────────── -->
<rect x="112" y="74" width="108" height="34" rx="3" fill="#fef0dc" stroke="#e8aa66" stroke-width="1.0"/>
<text x="166" y="87" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">scala3-0001</text>
<text x="166" y="100" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#cc6600">Constraint lattice</text>
<!-- ── HIGH chips (2 rows × 6, step=94) ─────────────────────────── -->
<!-- Row 1: y=122 -->
<rect x="112" y="122" width="90" height="34" rx="3" fill="#e8f5e8" stroke="#88bb88" stroke-width="0.8"/>
<text x="157" y="135" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">javac-0001</text>
<text x="157" y="148" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#558855">Tarjan stack</text>
<rect x="206" y="122" width="90" height="34" rx="3" fill="#e8f5e8" stroke="#88bb88" stroke-width="0.8"/>
<text x="251" y="135" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">javac-0002a/b</text>
<text x="251" y="148" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#558855">Infer closure</text>
<rect x="300" y="122" width="90" height="34" rx="3" fill="#e8f5e8" stroke="#88bb88" stroke-width="0.8"/>
<text x="345" y="135" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">javac-0004/5</text>
<text x="345" y="148" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#558855">Deps+Context</text>
<rect x="394" y="122" width="90" height="34" rx="3" fill="#eaf0f8" stroke="#88aacc" stroke-width="0.8"/>
<text x="439" y="135" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">kotlin-0001</text>
<text x="439" y="148" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#4477aa">Inheritance check</text>
<rect x="488" y="122" width="90" height="34" rx="3" fill="#eaf0f8" stroke="#88aacc" stroke-width="0.8"/>
<text x="533" y="135" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">ts-0001..3</text>
<text x="533" y="148" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#4477aa">TypeScript checker</text>
<rect x="582" y="122" width="90" height="34" rx="3" fill="#f0eaf8" stroke="#aa88cc" stroke-width="0.8"/>
<text x="627" y="135" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">ghc-0001..3</text>
<text x="627" y="148" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#7755aa">SCC / codegen</text>
<!-- Row 2: y=160 -->
<rect x="112" y="160" width="90" height="34" rx="3" fill="#f8f0ea" stroke="#cc9966" stroke-width="0.8"/>
<text x="157" y="173" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">llvm-0001</text>
<text x="157" y="186" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#aa7744">GlobalsModRef</text>
<rect x="206" y="160" width="90" height="34" rx="3" fill="#f8eeea" stroke="#cc8866" stroke-width="0.8"/>
<text x="251" y="173" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">rustc-0001</text>
<text x="251" y="186" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#aa6644">SmallVec::contains</text>
<rect x="300" y="160" width="90" height="34" rx="3" fill="#f5f0e8" stroke="#bbaa66" stroke-width="0.8"/>
<text x="345" y="173" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">erlang-0001</text>
<text x="345" y="186" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#887733">one_path/8</text>
<rect x="394" y="160" width="90" height="34" rx="3" fill="#eaf5f0" stroke="#66bb99" stroke-width="0.8"/>
<text x="439" y="173" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">frrouting-0001</text>
<text x="439" y="186" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#339966">ospf_ti_lfa ×5</text>
<!-- frrouting-0002 OPEN (dashed) -->
<rect x="488" y="160" width="90" height="34" rx="3" fill="#fff0f0" stroke="#cc6666" stroke-width="0.8" stroke-dasharray="4,2"/>
<text x="533" y="173" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">frrouting-0002</text>
<text x="533" y="186" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#cc4444">ospf_spf ⚠ OPEN</text>
<!-- create-0001 OPEN (dashed) -->
<rect x="582" y="160" width="90" height="34" rx="3" fill="#fce8e8" stroke="#e88888" stroke-width="0.8" stroke-dasharray="4,2"/>
<text x="627" y="173" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">create-0001</text>
<text x="627" y="186" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#cc4444">TrackGraph BFS ⚠</text>
<!-- ── MEDIUM chips ────────────────────────────────────────────────── -->
<rect x="112" y="208" width="90" height="34" rx="3" fill="#eeeef8" stroke="#9999cc" stroke-width="0.8"/>
<text x="157" y="221" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">javac-0003</text>
<text x="157" y="234" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#666688">ModuleHasher</text>
<rect x="206" y="208" width="90" height="34" rx="3" fill="#eeeef8" stroke="#9999cc" stroke-width="0.8"/>
<text x="251" y="221" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">gcc-0001</text>
<text x="251" y="234" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#666688">Johnson's gcov</text>
<rect x="300" y="208" width="90" height="34" rx="3" fill="#eeeef8" stroke="#9999cc" stroke-width="0.8"/>
<text x="345" y="221" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">rustc-0002</text>
<text x="345" y="234" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#666688">spec graph</text>
<rect x="394" y="208" width="90" height="34" rx="3" fill="#eeeef8" stroke="#9999cc" stroke-width="0.8"/>
<text x="439" y="221" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">cpython-0001</text>
<text x="439" y="234" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#666688">sccutils.py</text>
<!-- erlang-0002 FIXABLE (dashed) -->
<rect x="488" y="208" width="90" height="34" rx="3" fill="#f5f0ff" stroke="#aa88dd" stroke-width="0.8" stroke-dasharray="4,2"/>
<text x="533" y="221" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#333">erlang-0002</text>
<text x="533" y="234" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#7755aa">loop_vertices ↑ upstream</text>
<!-- ── LOW chips ───────────────────────────────────────────────────── -->
<rect x="112" y="256" width="90" height="36" rx="3" fill="#f5f5f5" stroke="#cccccc" stroke-width="0.6"/>
<text x="157" y="269" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#777">maven-0001..3</text>
<text x="157" y="282" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#999">build cycles</text>
<rect x="206" y="256" width="90" height="36" rx="3" fill="#f5f5f5" stroke="#cccccc" stroke-width="0.6"/>
<text x="251" y="269" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#777">cmake-0001</text>
<text x="251" y="282" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#999">dep scan</text>
<rect x="300" y="256" width="90" height="36" rx="3" fill="#f5f5f5" stroke="#cccccc" stroke-width="0.6"/>
<text x="345" y="269" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#777">sqlite-0001</text>
<text x="345" y="282" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#999">schema cycles</text>
<rect x="394" y="256" width="90" height="36" rx="3" fill="#f5f5f5" stroke="#cccccc" stroke-width="0.6"/>
<text x="439" y="269" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#777">composer-0001..2</text>
<text x="439" y="282" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#999">pkg resolver</text>
<!-- postgresql-0001..5 DEFERRED (dashed) -->
<rect x="488" y="256" width="90" height="36" rx="3" fill="#f8f8ee" stroke="#aaaa66" stroke-width="0.6" stroke-dasharray="3,2"/>
<text x="533" y="269" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#777">pg-0001..5</text>
<text x="533" y="282" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#aa9900">planner ··· deferred</text>
<!-- minecraft-0002 bounded (dashed) -->
<rect x="582" y="256" width="90" height="36" rx="3" fill="#f8f8f8" stroke="#aaaaaa" stroke-width="0.6" stroke-dasharray="3,2"/>
<text x="627" y="269" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="8" fill="#777">minecraft-0002</text>
<text x="627" y="282" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7" fill="#999">PistonResolver ≤12</text>
<!-- Legend: solid=patched, dashed=open/deferred -->
<rect x="686" y="208" width="10" height="10" rx="2" fill="#f5f5f5" stroke="#999" stroke-width="0.8"/>
<text x="700" y="218" font-family="Helvetica,sans-serif" font-size="7" fill="#777">patched</text>
<rect x="686" y="222" width="10" height="10" rx="2" fill="#fff0f0" stroke="#cc6666" stroke-width="0.8" stroke-dasharray="3,2"/>
<text x="700" y="232" font-family="Helvetica,sans-serif" font-size="7" fill="#777">open / deferred</text>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: defect_map Pages: 1 -->
<svg width="816pt" height="1426pt"
viewBox="0.00 0.00 816.05 1425.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 1396.8)">
<title>defect_map</title>
<polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-1396.8 787.25,-1396.8 787.25,28.8 -28.8,28.8"/>
<g id="clust1" class="cluster">
<title>cluster_exp</title>
<polygon fill="white" stroke="black" stroke-width="2.5" stroke-dasharray="5,2" points="8,-588 8,-676 169.66,-676 169.66,-588 8,-588"/>
<text text-anchor="middle" x="88.83" y="-664.8" font-family="Helvetica,sans-Serif" font-size="9.00">EXPONENTIAL</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_critical</title>
<polygon fill="white" stroke="black" stroke-width="2" points="12.95,-838 12.95,-912 164.71,-912 164.71,-838 12.95,-838"/>
<text text-anchor="middle" x="88.83" y="-900.8" font-family="Helvetica,sans-Serif" font-size="9.00">CRITICAL &#160;O(nu00b3)</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_high</title>
<polygon fill="white" stroke="black" stroke-width="1.5" points="284.66,-498 284.66,-1360 734.18,-1360 734.18,-498 284.66,-498"/>
<text text-anchor="middle" x="509.42" y="-1348.8" font-family="Helvetica,sans-Serif" font-size="9.00">HIGH &#160;O(nu00b2)</text>
</g>
<g id="clust4" class="cluster">
<title>cluster_med</title>
<polygon fill="white" stroke="black" points="571.81,-8 571.81,-490 750.45,-490 750.45,-8 571.81,-8"/>
<text text-anchor="middle" x="661.13" y="-478.8" font-family="Helvetica,sans-Serif" font-size="9.00">MEDIUM</text>
</g>
<g id="clust5" class="cluster">
<title>cluster_low</title>
<polygon fill="white" stroke="black" stroke-width="0.5" points="22.52,-997 22.52,-1283 155.14,-1283 155.14,-997 22.52,-997"/>
<text text-anchor="middle" x="88.83" y="-1271.8" font-family="Helvetica,sans-Serif" font-size="9.00">LOW</text>
</g>
<!-- mc1 -->
<g id="node1" class="node">
<title>mc1</title>
<ellipse fill="white" stroke="black" stroke-width="2.5" cx="88.83" cy="-623" rx="72.66" ry="26.74"/>
<text text-anchor="middle" x="88.83" y="-630.8" font-family="Helvetica,sans-Serif" font-size="9.00">minecraft&#45;0001</text>
<text text-anchor="middle" x="88.83" y="-620.8" font-family="Helvetica,sans-Serif" font-size="9.00">DependencySorter</text>
<text text-anchor="middle" x="88.83" y="-610.8" font-family="Helvetica,sans-Serif" font-size="9.00">O(E^D)</text>
</g>
<!-- pg -->
<g id="node14" class="node">
<title>pg</title>
<ellipse fill="white" stroke="black" stroke-dasharray="5,2" cx="369.74" cy="-623" rx="74.49" ry="26.74"/>
<text text-anchor="middle" x="369.74" y="-630.8" font-family="Helvetica,sans-Serif" font-size="9.00">postgresql&#45;0001..5</text>
<text text-anchor="middle" x="369.74" y="-620.8" font-family="Helvetica,sans-Serif" font-size="9.00">planner hot paths</text>
<text text-anchor="middle" x="369.74" y="-610.8" font-family="Helvetica,sans-Serif" font-size="9.00">[DEFERRED x5]</text>
</g>
<!-- mc1&#45;&gt;pg -->
<g id="edge4" class="edge">
<title>mc1&#45;&gt;pg</title>
<path fill="none" stroke="black" stroke-width="0.6" stroke-dasharray="1,5" d="M152.26,-609.64C185.32,-605.04 217.22,-606.74 293.48,-614.73"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="293.41,-616.48 298.56,-615.26 293.77,-613 293.41,-616.48"/>
<text text-anchor="middle" x="227.16" y="-643.6" font-family="Helvetica,sans-Serif" font-size="8.00">tag&#45;&gt;plan</text>
<text text-anchor="middle" x="227.16" y="-634.6" font-family="Helvetica,sans-Serif" font-size="8.00">both unvisited</text>
<text text-anchor="middle" x="227.16" y="-625.6" font-family="Helvetica,sans-Serif" font-size="8.00">DFS</text>
</g>
<!-- sc1 -->
<g id="node2" class="node">
<title>sc1</title>
<ellipse fill="white" stroke="black" stroke-width="2" cx="88.83" cy="-866" rx="67.76" ry="19.6"/>
<text text-anchor="middle" x="88.83" y="-868.8" font-family="Helvetica,sans-Serif" font-size="9.00">scala3&#45;0001</text>
<text text-anchor="middle" x="88.83" y="-858.8" font-family="Helvetica,sans-Serif" font-size="9.00">Constraint lattice</text>
</g>
<!-- jc1 -->
<g id="node3" class="node">
<title>jc1</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-706" rx="50.82" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-708.8" font-family="Helvetica,sans-Serif" font-size="9.00">javac&#45;0001</text>
<text text-anchor="middle" x="369.74" y="-698.8" font-family="Helvetica,sans-Serif" font-size="9.00">Tarjan stack</text>
</g>
<!-- er1 -->
<g id="node11" class="node">
<title>er1</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="661.13" cy="-706" rx="52.15" ry="19.6"/>
<text text-anchor="middle" x="661.13" y="-708.8" font-family="Helvetica,sans-Serif" font-size="9.00">erlang&#45;0001</text>
<text text-anchor="middle" x="661.13" y="-698.8" font-family="Helvetica,sans-Serif" font-size="9.00">one_path/8</text>
</g>
<!-- jc1&#45;&gt;er1 -->
<g id="edge1" class="edge">
<title>jc1&#45;&gt;er1</title>
<path fill="none" stroke="black" stroke-width="0.6" stroke-dasharray="1,5" d="M420.79,-708.32C529.7,-713.23 564.77,-714.25 604.86,-711.38"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="605.44,-713.09 610.3,-710.97 605.18,-709.6 605.44,-713.09"/>
<text text-anchor="middle" x="513.31" y="-708.6" font-family="Helvetica,sans-Serif" font-size="8.00">pattern</text>
</g>
<!-- er2 -->
<g id="node20" class="node">
<title>er2</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" stroke-dasharray="5,2" cx="661.13" cy="-133" rx="81.13" ry="26.74"/>
<text text-anchor="middle" x="661.13" y="-140.8" font-family="Helvetica,sans-Serif" font-size="9.00">erlang&#45;0002</text>
<text text-anchor="middle" x="661.13" y="-130.8" font-family="Helvetica,sans-Serif" font-size="9.00">loop_vertices</text>
<text text-anchor="middle" x="661.13" y="-120.8" font-family="Helvetica,sans-Serif" font-size="9.00">[FIXABLE&#45;UPSTREAM]</text>
</g>
<!-- jc1&#45;&gt;er2 -->
<g id="edge2" class="edge">
<title>jc1&#45;&gt;er2</title>
<path fill="none" stroke="black" stroke-width="0.6" stroke-dasharray="1,5" d="M379.76,-686.37C561.52,-330.24 574.72,-304.35 645.28,-164.42"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="646.91,-165.08 647.6,-159.82 643.79,-163.5 646.91,-165.08"/>
<text text-anchor="middle" x="513.31" y="-401.6" font-family="Helvetica,sans-Serif" font-size="8.00">same fix</text>
<text text-anchor="middle" x="513.31" y="-392.6" font-family="Helvetica,sans-Serif" font-size="8.00">(parallel set)</text>
</g>
<!-- jc2 -->
<g id="node4" class="node">
<title>jc2</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-1238" rx="58.88" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-1240.8" font-family="Helvetica,sans-Serif" font-size="9.00">javac&#45;0002a/b</text>
<text text-anchor="middle" x="369.74" y="-1230.8" font-family="Helvetica,sans-Serif" font-size="9.00">Infer closure</text>
</g>
<!-- jc45 -->
<g id="node5" class="node">
<title>jc45</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-1162" rx="59.29" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-1164.8" font-family="Helvetica,sans-Serif" font-size="9.00">javac&#45;0004/5</text>
<text text-anchor="middle" x="369.74" y="-1154.8" font-family="Helvetica,sans-Serif" font-size="9.00">Deps+Context</text>
</g>
<!-- ts -->
<g id="node6" class="node">
<title>ts</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-1086" rx="74.49" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-1088.8" font-family="Helvetica,sans-Serif" font-size="9.00">ts&#45;0001..3</text>
<text text-anchor="middle" x="369.74" y="-1078.8" font-family="Helvetica,sans-Serif" font-size="9.00">TypeScript checker</text>
</g>
<!-- ghc -->
<g id="node7" class="node">
<title>ghc</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-1010" rx="55.72" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-1012.8" font-family="Helvetica,sans-Serif" font-size="9.00">ghc&#45;0001..3</text>
<text text-anchor="middle" x="369.74" y="-1002.8" font-family="Helvetica,sans-Serif" font-size="9.00">SCC/codegen</text>
</g>
<!-- kt -->
<g id="node8" class="node">
<title>kt</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-934" rx="70.92" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-936.8" font-family="Helvetica,sans-Serif" font-size="9.00">kotlin&#45;0001</text>
<text text-anchor="middle" x="369.74" y="-926.8" font-family="Helvetica,sans-Serif" font-size="9.00">Inheritance check</text>
</g>
<!-- ll -->
<g id="node9" class="node">
<title>ll</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-858" rx="59.29" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-860.8" font-family="Helvetica,sans-Serif" font-size="9.00">llvm&#45;0001</text>
<text text-anchor="middle" x="369.74" y="-850.8" font-family="Helvetica,sans-Serif" font-size="9.00">GlobalsModRef</text>
</g>
<!-- rc -->
<g id="node10" class="node">
<title>rc</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-782" rx="72.66" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-784.8" font-family="Helvetica,sans-Serif" font-size="9.00">rustc&#45;0001</text>
<text text-anchor="middle" x="369.74" y="-774.8" font-family="Helvetica,sans-Serif" font-size="9.00">SmallVec::contains</text>
</g>
<!-- fr1 -->
<g id="node12" class="node">
<title>fr1</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" cx="369.74" cy="-1314" rx="60.21" ry="19.6"/>
<text text-anchor="middle" x="369.74" y="-1316.8" font-family="Helvetica,sans-Serif" font-size="9.00">frrouting&#45;0001</text>
<text text-anchor="middle" x="369.74" y="-1306.8" font-family="Helvetica,sans-Serif" font-size="9.00">ospf_ti_lfa x5</text>
</g>
<!-- fr2 -->
<g id="node13" class="node">
<title>fr2</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" cx="661.13" cy="-1307" rx="65.11" ry="26.74"/>
<text text-anchor="middle" x="661.13" y="-1314.8" font-family="Helvetica,sans-Serif" font-size="9.00">frrouting&#45;0002</text>
<text text-anchor="middle" x="661.13" y="-1304.8" font-family="Helvetica,sans-Serif" font-size="9.00">ospf_spf Dijkstra</text>
<text text-anchor="middle" x="661.13" y="-1294.8" font-family="Helvetica,sans-Serif" font-size="9.00">[UNPATCHED]</text>
</g>
<!-- fr1&#45;&gt;fr2 -->
<g id="edge3" class="edge">
<title>fr1&#45;&gt;fr2</title>
<path fill="none" stroke="black" stroke-width="0.6" d="M412.18,-1328.25C510.93,-1360.87 534.74,-1362.11 612.13,-1328.88"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="612.93,-1330.44 616.82,-1326.85 611.54,-1327.23 612.93,-1330.44"/>
<text text-anchor="middle" x="513.31" y="-1312.6" font-family="Helvetica,sans-Serif" font-size="8.00">same package</text>
</g>
<!-- cr1 -->
<g id="node15" class="node">
<title>cr1</title>
<ellipse fill="white" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" cx="369.74" cy="-533" rx="77.15" ry="26.74"/>
<text text-anchor="middle" x="369.74" y="-540.8" font-family="Helvetica,sans-Serif" font-size="9.00">create&#45;0001</text>
<text text-anchor="middle" x="369.74" y="-530.8" font-family="Helvetica,sans-Serif" font-size="9.00">TrackGraph BFS</text>
<text text-anchor="middle" x="369.74" y="-520.8" font-family="Helvetica,sans-Serif" font-size="9.00">ArrayList.remove(0)</text>
</g>
<!-- jc3 -->
<g id="node16" class="node">
<title>jc3</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="661.13" cy="-444" rx="57.97" ry="19.6"/>
<text text-anchor="middle" x="661.13" y="-446.8" font-family="Helvetica,sans-Serif" font-size="9.00">javac&#45;0003</text>
<text text-anchor="middle" x="661.13" y="-436.8" font-family="Helvetica,sans-Serif" font-size="9.00">ModuleHasher</text>
</g>
<!-- gcc -->
<g id="node17" class="node">
<title>gcc</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="661.13" cy="-368" rx="60.62" ry="19.6"/>
<text text-anchor="middle" x="661.13" y="-370.8" font-family="Helvetica,sans-Serif" font-size="9.00">gcc&#45;0001</text>
<text text-anchor="middle" x="661.13" y="-360.8" font-family="Helvetica,sans-Serif" font-size="9.00">Johnson&#39;s gcov</text>
</g>
<!-- rc2 -->
<g id="node18" class="node">
<title>rc2</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="661.13" cy="-292" rx="49.49" ry="19.6"/>
<text text-anchor="middle" x="661.13" y="-294.8" font-family="Helvetica,sans-Serif" font-size="9.00">rustc&#45;0002</text>
<text text-anchor="middle" x="661.13" y="-284.8" font-family="Helvetica,sans-Serif" font-size="9.00">spec graph</text>
</g>
<!-- cp -->
<g id="node19" class="node">
<title>cp</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" cx="661.13" cy="-216" rx="58.88" ry="19.6"/>
<text text-anchor="middle" x="661.13" y="-218.8" font-family="Helvetica,sans-Serif" font-size="9.00">cpython&#45;0001</text>
<text text-anchor="middle" x="661.13" y="-208.8" font-family="Helvetica,sans-Serif" font-size="9.00">sccutils.py</text>
</g>
<!-- mc2 -->
<g id="node21" class="node">
<title>mc2</title>
<ellipse fill="white" stroke="black" stroke-width="0.8" stroke-dasharray="5,2" cx="661.13" cy="-43" rx="62.87" ry="26.74"/>
<text text-anchor="middle" x="661.13" y="-50.8" font-family="Helvetica,sans-Serif" font-size="9.00">minecraft&#45;0002</text>
<text text-anchor="middle" x="661.13" y="-40.8" font-family="Helvetica,sans-Serif" font-size="9.00">PistonResolver</text>
<text text-anchor="middle" x="661.13" y="-30.8" font-family="Helvetica,sans-Serif" font-size="9.00">bounded&lt;=12</text>
</g>
<!-- mv -->
<g id="node22" class="node">
<title>mv</title>
<ellipse fill="white" stroke="black" stroke-width="0.5" cx="88.83" cy="-1239" rx="50.61" ry="18"/>
<text text-anchor="middle" x="88.83" y="-1236.8" font-family="Helvetica,sans-Serif" font-size="9.00">maven&#45;0001..3</text>
</g>
<!-- cm -->
<g id="node23" class="node">
<title>cm</title>
<ellipse fill="white" stroke="black" stroke-width="0.5" cx="88.83" cy="-1167" rx="43.76" ry="18"/>
<text text-anchor="middle" x="88.83" y="-1164.8" font-family="Helvetica,sans-Serif" font-size="9.00">cmake&#45;0001</text>
</g>
<!-- sq -->
<g id="node24" class="node">
<title>sq</title>
<ellipse fill="white" stroke="black" stroke-width="0.5" cx="88.83" cy="-1095" rx="40.33" ry="18"/>
<text text-anchor="middle" x="88.83" y="-1092.8" font-family="Helvetica,sans-Serif" font-size="9.00">sqlite&#45;0001</text>
</g>
<!-- co -->
<g id="node25" class="node">
<title>co</title>
<ellipse fill="white" stroke="black" stroke-width="0.5" cx="88.83" cy="-1023" rx="58.13" ry="18"/>
<text text-anchor="middle" x="88.83" y="-1020.8" font-family="Helvetica,sans-Serif" font-size="9.00">composer&#45;0001..2</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -1,67 +1,67 @@
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="380" style="background:white;font-family:Helvetica,Arial,sans-serif;">
<text x="20" y="26" font-size="12" font-weight="500" fill="#222222">javac — CWE-407 Speedups</text>
<text x="20" y="42" font-size="8.5" fill="#888888">OpenJDK javac · 5 defects · all patched upstream · measured at production scale</text>
<text x="180" y="170" text-anchor="middle" font-size="22" font-weight="600" fill="#222222">20.9×</text>
<text x="180" y="188" text-anchor="middle" font-size="8" fill="#888888">peak speedup</text>
<text x="180" y="200" text-anchor="middle" font-size="7.5" fill="#888888">measured</text>
<path d="M 180.00,-80.00 A 260,260 0 1,1 179.55,-80.00 L 179.60,-52.00 A 232,232 0 1,0 180.00,-52.00 Z" fill="#f5f5f5"/>
<path d="M 417.37,73.90 A 260,260 0 1,1 179.55,-80.00 L 179.60,-52.00 A 232,232 0 1,0 391.80,85.33 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,-80.00 A 260,260 0 0,1 417.37,73.90 L 391.80,85.33 A 232,232 0 0,0 180.00,-52.00 Z" fill="#aacbaa"/>
<rect x="390" y="64" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="76" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="72" font-size="7.5" fill="#888888">0001</text>
<text x="404" y="83" font-size="8.5" font-weight="500" fill="#222222">Tarjan stack.contains()</text>
<text x="404" y="95" font-size="8" fill="#cc6666">5.46× — V=800</text>
<text x="404" y="106" font-size="7.5" fill="#888888">before arc = 82% of time</text>
<path d="M 180.00,-47.00 A 227,227 0 1,1 179.60,-47.00 L 179.65,-19.00 A 199,199 0 1,0 180.00,-19.00 Z" fill="#f5f5f5"/>
<path d="M 360.00,41.70 A 227,227 0 1,1 179.60,-47.00 L 179.65,-19.00 A 199,199 0 1,0 337.80,58.76 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,-47.00 A 227,227 0 0,1 360.00,41.70 L 337.80,58.76 A 199,199 0 0,0 180.00,-19.00 Z" fill="#aacbaa"/>
<rect x="390" y="110" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="122" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="118" font-size="7.5" fill="#888888">0002a</text>
<text x="404" y="129" font-size="8.5" font-weight="500" fill="#222222">findNode ArrayList scan</text>
<text x="404" y="141" font-size="8" fill="#cc6666">6.9× — N=200</text>
<text x="404" y="152" font-size="7.5" fill="#888888">before arc = 85% of time</text>
<path d="M 180.00,-14.00 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 180.00,14.00 Z" fill="#f5f5f5"/>
<path d="M 237.41,-5.31 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 229.12,21.43 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,-14.00 A 194,194 0 0,1 237.41,-5.31 L 229.12,21.43 A 166,166 0 0,0 180.00,14.00 Z" fill="#aacbaa"/>
<rect x="390" y="156" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="168" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="164" font-size="7.5" fill="#888888">0002b</text>
<text x="404" y="175" font-size="8.5" font-weight="500" fill="#222222">closure uncached DFS</text>
<text x="404" y="187" font-size="8" fill="#cc6666">20.9× — V=100</text>
<text x="404" y="198" font-size="7.5" fill="#888888">before arc = 95% of time</text>
<path d="M 180.00,19.00 A 161,161 0 1,1 179.72,19.00 L 179.77,47.00 A 133,133 0 1,0 180.00,47.00 Z" fill="#f5f5f5"/>
<path d="M 42.95,264.49 A 161,161 0 0,1 179.72,19.00 L 179.77,47.00 A 133,133 0 0,0 66.79,249.80 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,19.00 A 161,161 0 1,1 42.95,264.49 L 66.79,249.80 A 133,133 0 1,0 180.00,47.00 Z" fill="#aacbaa"/>
<rect x="390" y="202" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="214" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="210" font-size="7.5" fill="#888888">0003</text>
<text x="404" y="221" font-size="8.5" font-weight="500" fill="#222222">TopoSorter Deque.contains()</text>
<text x="404" y="233" font-size="8" fill="#cc6666">1.5× — V=200</text>
<text x="404" y="244" font-size="7.5" fill="#888888">before arc = 34% of time</text>
<path d="M 180.00,52.00 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 180.00,80.00 Z" fill="#f5f5f5"/>
<path d="M 307.36,167.26 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 279.50,170.04 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,52.00 A 128,128 0 0,1 307.36,167.26 L 279.50,170.04 A 100,100 0 0,0 180.00,80.00 Z" fill="#aacbaa"/>
<rect x="390" y="248" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="260" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="256" font-size="7.5" fill="#888888">0004</text>
<text x="404" y="267" font-size="8.5" font-weight="500" fill="#222222">DependencyList.add</text>
<text x="404" y="279" font-size="8" fill="#cc6666">4.3× — M=200</text>
<text x="404" y="290" font-size="7.5" fill="#888888">before arc = 77% of time</text>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#f5f5f5"/>
<path d="M 227.56,262.24 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 213.54,238.00 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,85.00 A 95,95 0 0,1 227.56,262.24 L 213.54,238.00 A 67,67 0 0,0 180.00,113.00 Z" fill="#aacbaa"/>
<rect x="390" y="294" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="306" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="302" font-size="7.5" fill="#888888">0005</text>
<text x="404" y="313" font-size="8.5" font-weight="500" fill="#222222">BoundSet containsAll</text>
<text x="404" y="325" font-size="8" fill="#cc6666">2.4× — B=100</text>
<text x="404" y="336" font-size="7.5" fill="#888888">before arc = 58% of time</text>
<text x="390" y="60" font-size="8" fill="#888888" font-weight="600">DEFECTS (outer → inner ring)</text>
<rect x="20" y="352" width="12" height="12" fill="#e8aaaa" rx="2"/>
<text x="36" y="361" font-size="8" fill="#888888">BEFORE — wasted time</text>
<rect x="160" y="352" width="12" height="12" fill="#aacbaa" rx="2"/>
<text x="176" y="361" font-size="8" fill="#888888">AFTER — time with fix</text>
<text x="310" y="361" font-size="7.5" fill="#888888">Arc ∝ fraction of BEFORE time. Green = fixed portion.</text>
<text x="20" y="26" font-size="12" font-weight="500" fill="#000000">javac — CWE-407 Speedups</text>
<text x="20" y="42" font-size="8.5" fill="#444444">OpenJDK javac · 5 defects · all patched upstream · measured at production scale</text>
<text x="180" y="170" text-anchor="middle" font-size="22" font-weight="600" fill="#000000">20.9×</text>
<text x="180" y="188" text-anchor="middle" font-size="8" fill="#444444">peak speedup</text>
<text x="180" y="200" text-anchor="middle" font-size="7.5" fill="#444444">measured</text>
<path d="M 180.00,-80.00 A 260,260 0 1,1 179.55,-80.00 L 179.60,-52.00 A 232,232 0 1,0 180.00,-52.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 417.37,73.90 A 260,260 0 1,1 179.55,-80.00 L 179.60,-52.00 A 232,232 0 1,0 391.80,85.33 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,-80.00 A 260,260 0 0,1 417.37,73.90 L 391.80,85.33 A 232,232 0 0,0 180.00,-52.00 Z" fill="#dddddd"/>
<rect x="390" y="64" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="76" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="72" font-size="7.5" fill="#444444">0001</text>
<text x="404" y="83" font-size="8.5" font-weight="500" fill="#000000">Tarjan stack.contains()</text>
<text x="404" y="95" font-size="8" fill="#000000" font-weight="600">5.46× — V=800</text>
<text x="404" y="106" font-size="7.5" fill="#444444">before arc = 82% of time</text>
<path d="M 180.00,-47.00 A 227,227 0 1,1 179.60,-47.00 L 179.65,-19.00 A 199,199 0 1,0 180.00,-19.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 360.00,41.70 A 227,227 0 1,1 179.60,-47.00 L 179.65,-19.00 A 199,199 0 1,0 337.80,58.76 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,-47.00 A 227,227 0 0,1 360.00,41.70 L 337.80,58.76 A 199,199 0 0,0 180.00,-19.00 Z" fill="#dddddd"/>
<rect x="390" y="110" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="122" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="118" font-size="7.5" fill="#444444">0002a</text>
<text x="404" y="129" font-size="8.5" font-weight="500" fill="#000000">findNode ArrayList scan</text>
<text x="404" y="141" font-size="8" fill="#000000" font-weight="600">6.9× — N=200</text>
<text x="404" y="152" font-size="7.5" fill="#444444">before arc = 85% of time</text>
<path d="M 180.00,-14.00 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 180.00,14.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 237.41,-5.31 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 229.12,21.43 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,-14.00 A 194,194 0 0,1 237.41,-5.31 L 229.12,21.43 A 166,166 0 0,0 180.00,14.00 Z" fill="#dddddd"/>
<rect x="390" y="156" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="168" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="164" font-size="7.5" fill="#444444">0002b</text>
<text x="404" y="175" font-size="8.5" font-weight="500" fill="#000000">closure uncached DFS</text>
<text x="404" y="187" font-size="8" fill="#000000" font-weight="600">20.9× — V=100</text>
<text x="404" y="198" font-size="7.5" fill="#444444">before arc = 95% of time</text>
<path d="M 180.00,19.00 A 161,161 0 1,1 179.72,19.00 L 179.77,47.00 A 133,133 0 1,0 180.00,47.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 42.95,264.49 A 161,161 0 0,1 179.72,19.00 L 179.77,47.00 A 133,133 0 0,0 66.79,249.80 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,19.00 A 161,161 0 1,1 42.95,264.49 L 66.79,249.80 A 133,133 0 1,0 180.00,47.00 Z" fill="#dddddd"/>
<rect x="390" y="202" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="214" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="210" font-size="7.5" fill="#444444">0003</text>
<text x="404" y="221" font-size="8.5" font-weight="500" fill="#000000">TopoSorter Deque.contains()</text>
<text x="404" y="233" font-size="8" fill="#000000" font-weight="600">1.5× — V=200</text>
<text x="404" y="244" font-size="7.5" fill="#444444">before arc = 34% of time</text>
<path d="M 180.00,52.00 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 180.00,80.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 307.36,167.26 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 279.50,170.04 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,52.00 A 128,128 0 0,1 307.36,167.26 L 279.50,170.04 A 100,100 0 0,0 180.00,80.00 Z" fill="#dddddd"/>
<rect x="390" y="248" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="260" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="256" font-size="7.5" fill="#444444">0004</text>
<text x="404" y="267" font-size="8.5" font-weight="500" fill="#000000">DependencyList.add</text>
<text x="404" y="279" font-size="8" fill="#000000" font-weight="600">4.3× — M=200</text>
<text x="404" y="290" font-size="7.5" fill="#444444">before arc = 77% of time</text>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 227.56,262.24 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 213.54,238.00 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,85.00 A 95,95 0 0,1 227.56,262.24 L 213.54,238.00 A 67,67 0 0,0 180.00,113.00 Z" fill="#dddddd"/>
<rect x="390" y="294" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="306" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="302" font-size="7.5" fill="#444444">0005</text>
<text x="404" y="313" font-size="8.5" font-weight="500" fill="#000000">BoundSet containsAll</text>
<text x="404" y="325" font-size="8" fill="#000000" font-weight="600">2.4× — B=100</text>
<text x="404" y="336" font-size="7.5" fill="#444444">before arc = 58% of time</text>
<text x="390" y="60" font-size="8" fill="#444444" font-weight="600">DEFECTS (outer → inner ring)</text>
<rect x="20" y="352" width="12" height="12" fill="#555555" rx="2"/>
<text x="36" y="361" font-size="8" fill="#444444">BEFORE — wasted time (dark)</text>
<rect x="180" y="352" width="12" height="12" fill="#dddddd" stroke="#999" stroke-width="0.5" rx="2"/>
<text x="196" y="361" font-size="8" fill="#444444">AFTER — time with fix (light)</text>
<text x="350" y="361" font-size="7.5" fill="#444444">Arc proportional to fraction of BEFORE time.</text>
</svg>

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before After
Before After

View file

@ -1,48 +1,48 @@
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="380" style="background:white;font-family:Helvetica,Arial,sans-serif;">
<text x="20" y="26" font-size="12" font-weight="500" fill="#222222">Minecraft Client — CWE-407 Impact</text>
<text x="20" y="42" font-size="8.5" fill="#888888">Single-player · same defective classes · modpack world load + in-game</text>
<text x="180" y="170" text-anchor="middle" font-size="22" font-weight="600" fill="#222222">110.9×</text>
<text x="180" y="188" text-anchor="middle" font-size="8" fill="#888888">peak speedup</text>
<text x="180" y="200" text-anchor="middle" font-size="7.5" fill="#888888">measured</text>
<path d="M 180.00,-14.00 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 180.00,14.00 Z" fill="#f5f5f5"/>
<path d="M 190.98,-13.69 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 189.40,14.27 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,-14.00 A 194,194 0 0,1 190.98,-13.69 L 189.40,14.27 A 166,166 0 0,0 180.00,14.00 Z" fill="#aacbaa"/>
<rect x="390" y="64" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="76" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="72" font-size="7.5" fill="#888888">mc-0001</text>
<text x="404" y="83" font-size="8.5" font-weight="500" fill="#222222">DependencySorter (world load)</text>
<text x="404" y="95" font-size="8" fill="#cc6666">110.9× — depth 14</text>
<text x="404" y="106" font-size="7.5" fill="#888888">before arc = 99% of time</text>
<path d="M 180.00,19.00 A 161,161 0 1,1 179.72,19.00 L 179.77,47.00 A 133,133 0 1,0 180.00,47.00 Z" fill="#f5f5f5"/>
<path d="M 92.74,44.70 A 161,161 0 0,1 179.72,19.00 L 179.77,47.00 A 133,133 0 0,0 107.92,68.23 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,19.00 A 161,161 0 1,1 92.74,44.70 L 107.92,68.23 A 133,133 0 1,0 180.00,47.00 Z" fill="#aacbaa"/>
<rect x="390" y="110" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="122" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="118" font-size="7.5" fill="#888888">mc-0002</text>
<text x="404" y="129" font-size="8.5" font-weight="500" fill="#222222">PistonStructureResolver</text>
<text x="404" y="141" font-size="8" fill="#cc6666">1.1× — bounded ≤12</text>
<text x="404" y="152" font-size="7.5" fill="#888888">before arc = 9% of time</text>
<path d="M 180.00,52.00 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 180.00,80.00 Z" fill="#f5f5f5"/>
<path d="M 211.82,56.02 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 204.86,83.14 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,52.00 A 128,128 0 0,1 211.82,56.02 L 204.86,83.14 A 100,100 0 0,0 180.00,80.00 Z" fill="#aacbaa"/>
<rect x="390" y="156" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="168" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="164" font-size="7.5" fill="#888888">mc-0003</text>
<text x="404" y="175" font-size="8.5" font-weight="500" fill="#222222">ExpRedstoneWireEval (redstone)</text>
<text x="404" y="187" font-size="8" fill="#cc6666">~25× — N=500 wires</text>
<text x="404" y="198" font-size="7.5" fill="#888888">before arc = 96% of time</text>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#f5f5f5"/>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#aacbaa"/>
<rect x="390" y="202" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="214" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="210" font-size="7.5" fill="#888888">mc-0004</text>
<text x="404" y="221" font-size="8.5" font-weight="500" fill="#222222">MoveThroughVillageGoal (AI)</text>
<text x="404" y="233" font-size="8" fill="#cc6666">~1.0× — bounded ≤15</text>
<text x="404" y="244" font-size="7.5" fill="#888888">before arc = 0% of time</text>
<text x="390" y="60" font-size="8" fill="#888888" font-weight="600">DEFECTS (outer → inner ring)</text>
<rect x="20" y="352" width="12" height="12" fill="#e8aaaa" rx="2"/>
<text x="36" y="361" font-size="8" fill="#888888">BEFORE — wasted time</text>
<rect x="160" y="352" width="12" height="12" fill="#aacbaa" rx="2"/>
<text x="176" y="361" font-size="8" fill="#888888">AFTER — time with fix</text>
<text x="310" y="361" font-size="7.5" fill="#888888">Arc ∝ fraction of BEFORE time. Green = fixed portion.</text>
<text x="20" y="26" font-size="12" font-weight="500" fill="#000000">Minecraft Client — CWE-407 Impact</text>
<text x="20" y="42" font-size="8.5" fill="#444444">Single-player · same defective classes · modpack world load + in-game</text>
<text x="180" y="170" text-anchor="middle" font-size="22" font-weight="600" fill="#000000">110.9×</text>
<text x="180" y="188" text-anchor="middle" font-size="8" fill="#444444">peak speedup</text>
<text x="180" y="200" text-anchor="middle" font-size="7.5" fill="#444444">measured</text>
<path d="M 180.00,-14.00 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 180.00,14.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 190.98,-13.69 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 189.40,14.27 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,-14.00 A 194,194 0 0,1 190.98,-13.69 L 189.40,14.27 A 166,166 0 0,0 180.00,14.00 Z" fill="#dddddd"/>
<rect x="390" y="64" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="76" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="72" font-size="7.5" fill="#444444">mc-0001</text>
<text x="404" y="83" font-size="8.5" font-weight="500" fill="#000000">DependencySorter (world load)</text>
<text x="404" y="95" font-size="8" fill="#000000" font-weight="600">110.9× — depth 14</text>
<text x="404" y="106" font-size="7.5" fill="#444444">before arc = 99% of time</text>
<path d="M 180.00,19.00 A 161,161 0 1,1 179.72,19.00 L 179.77,47.00 A 133,133 0 1,0 180.00,47.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 92.74,44.70 A 161,161 0 0,1 179.72,19.00 L 179.77,47.00 A 133,133 0 0,0 107.92,68.23 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,19.00 A 161,161 0 1,1 92.74,44.70 L 107.92,68.23 A 133,133 0 1,0 180.00,47.00 Z" fill="#dddddd"/>
<rect x="390" y="110" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="122" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="118" font-size="7.5" fill="#444444">mc-0002</text>
<text x="404" y="129" font-size="8.5" font-weight="500" fill="#000000">PistonStructureResolver</text>
<text x="404" y="141" font-size="8" fill="#000000" font-weight="600">1.1× — bounded ≤12</text>
<text x="404" y="152" font-size="7.5" fill="#444444">before arc = 9% of time</text>
<path d="M 180.00,52.00 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 180.00,80.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 211.82,56.02 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 204.86,83.14 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,52.00 A 128,128 0 0,1 211.82,56.02 L 204.86,83.14 A 100,100 0 0,0 180.00,80.00 Z" fill="#dddddd"/>
<rect x="390" y="156" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="168" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="164" font-size="7.5" fill="#444444">mc-0003</text>
<text x="404" y="175" font-size="8.5" font-weight="500" fill="#000000">ExpRedstoneWireEval (redstone)</text>
<text x="404" y="187" font-size="8" fill="#000000" font-weight="600">~25× — N=500 wires</text>
<text x="404" y="198" font-size="7.5" fill="#444444">before arc = 96% of time</text>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#dddddd"/>
<rect x="390" y="202" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="214" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="210" font-size="7.5" fill="#444444">mc-0004</text>
<text x="404" y="221" font-size="8.5" font-weight="500" fill="#000000">MoveThroughVillageGoal (AI)</text>
<text x="404" y="233" font-size="8" fill="#000000" font-weight="600">~1.0× — bounded ≤15</text>
<text x="404" y="244" font-size="7.5" fill="#444444">before arc = 0% of time</text>
<text x="390" y="60" font-size="8" fill="#444444" font-weight="600">DEFECTS (outer → inner ring)</text>
<rect x="20" y="352" width="12" height="12" fill="#555555" rx="2"/>
<text x="36" y="361" font-size="8" fill="#444444">BEFORE — wasted time (dark)</text>
<rect x="180" y="352" width="12" height="12" fill="#dddddd" stroke="#999" stroke-width="0.5" rx="2"/>
<text x="196" y="361" font-size="8" fill="#444444">AFTER — time with fix (light)</text>
<text x="350" y="361" font-size="7.5" fill="#444444">Arc proportional to fraction of BEFORE time.</text>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before After
Before After

View file

@ -1,48 +1,48 @@
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="380" style="background:white;font-family:Helvetica,Arial,sans-serif;">
<text x="20" y="26" font-size="12" font-weight="500" fill="#222222">Minecraft Server-26.1 — CWE-407 Speedups</text>
<text x="20" y="42" font-size="8.5" fill="#888888">server-26.1-all-patched.jar · 4 defects · world load / game loop / redstone</text>
<text x="180" y="170" text-anchor="middle" font-size="22" font-weight="600" fill="#222222">110.9×</text>
<text x="180" y="188" text-anchor="middle" font-size="8" fill="#888888">peak speedup</text>
<text x="180" y="200" text-anchor="middle" font-size="7.5" fill="#888888">measured</text>
<path d="M 180.00,-14.00 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 180.00,14.00 Z" fill="#f5f5f5"/>
<path d="M 190.98,-13.69 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 189.40,14.27 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,-14.00 A 194,194 0 0,1 190.98,-13.69 L 189.40,14.27 A 166,166 0 0,0 180.00,14.00 Z" fill="#aacbaa"/>
<rect x="390" y="64" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="76" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="72" font-size="7.5" fill="#888888">mc-0001</text>
<text x="404" y="83" font-size="8.5" font-weight="500" fill="#222222">DependencySorter.isCyclic</text>
<text x="404" y="95" font-size="8" fill="#cc6666">110.9× — depth 14</text>
<text x="404" y="106" font-size="7.5" fill="#888888">before arc = 99% of time</text>
<path d="M 180.00,19.00 A 161,161 0 1,1 179.72,19.00 L 179.77,47.00 A 133,133 0 1,0 180.00,47.00 Z" fill="#f5f5f5"/>
<path d="M 92.74,44.70 A 161,161 0 0,1 179.72,19.00 L 179.77,47.00 A 133,133 0 0,0 107.92,68.23 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,19.00 A 161,161 0 1,1 92.74,44.70 L 107.92,68.23 A 133,133 0 1,0 180.00,47.00 Z" fill="#aacbaa"/>
<rect x="390" y="110" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="122" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="118" font-size="7.5" fill="#888888">mc-0002</text>
<text x="404" y="129" font-size="8.5" font-weight="500" fill="#222222">PistonStructureResolver</text>
<text x="404" y="141" font-size="8" fill="#cc6666">1.1× — bounded ≤12</text>
<text x="404" y="152" font-size="7.5" fill="#888888">before arc = 9% of time</text>
<path d="M 180.00,52.00 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 180.00,80.00 Z" fill="#f5f5f5"/>
<path d="M 211.82,56.02 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 204.86,83.14 Z" fill="#e8aaaa" opacity="0.75"/>
<path d="M 180.00,52.00 A 128,128 0 0,1 211.82,56.02 L 204.86,83.14 A 100,100 0 0,0 180.00,80.00 Z" fill="#aacbaa"/>
<rect x="390" y="156" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="168" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="164" font-size="7.5" fill="#888888">mc-0003</text>
<text x="404" y="175" font-size="8.5" font-weight="500" fill="#222222">ExpRedstoneWireEvaluator</text>
<text x="404" y="187" font-size="8" fill="#cc6666">~25× — N=500 wires</text>
<text x="404" y="198" font-size="7.5" fill="#888888">before arc = 96% of time</text>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#f5f5f5"/>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#aacbaa"/>
<rect x="390" y="202" width="10" height="10" fill="#e8aaaa" rx="2"/>
<rect x="390" y="214" width="10" height="3" fill="#aacbaa" rx="1"/>
<text x="404" y="210" font-size="7.5" fill="#888888">mc-0004</text>
<text x="404" y="221" font-size="8.5" font-weight="500" fill="#222222">MoveThroughVillageGoal</text>
<text x="404" y="233" font-size="8" fill="#cc6666">~1.0× — bounded ≤15</text>
<text x="404" y="244" font-size="7.5" fill="#888888">before arc = 0% of time</text>
<text x="390" y="60" font-size="8" fill="#888888" font-weight="600">DEFECTS (outer → inner ring)</text>
<rect x="20" y="352" width="12" height="12" fill="#e8aaaa" rx="2"/>
<text x="36" y="361" font-size="8" fill="#888888">BEFORE — wasted time</text>
<rect x="160" y="352" width="12" height="12" fill="#aacbaa" rx="2"/>
<text x="176" y="361" font-size="8" fill="#888888">AFTER — time with fix</text>
<text x="310" y="361" font-size="7.5" fill="#888888">Arc ∝ fraction of BEFORE time. Green = fixed portion.</text>
<text x="20" y="26" font-size="12" font-weight="500" fill="#000000">Minecraft Server-26.1 — CWE-407 Speedups</text>
<text x="20" y="42" font-size="8.5" fill="#444444">server-26.1-all-patched.jar · 4 defects · world load / game loop / redstone</text>
<text x="180" y="170" text-anchor="middle" font-size="22" font-weight="600" fill="#000000">110.9×</text>
<text x="180" y="188" text-anchor="middle" font-size="8" fill="#444444">peak speedup</text>
<text x="180" y="200" text-anchor="middle" font-size="7.5" fill="#444444">measured</text>
<path d="M 180.00,-14.00 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 180.00,14.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 190.98,-13.69 A 194,194 0 1,1 179.66,-14.00 L 179.71,14.00 A 166,166 0 1,0 189.40,14.27 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,-14.00 A 194,194 0 0,1 190.98,-13.69 L 189.40,14.27 A 166,166 0 0,0 180.00,14.00 Z" fill="#dddddd"/>
<rect x="390" y="64" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="76" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="72" font-size="7.5" fill="#444444">mc-0001</text>
<text x="404" y="83" font-size="8.5" font-weight="500" fill="#000000">DependencySorter.isCyclic</text>
<text x="404" y="95" font-size="8" fill="#000000" font-weight="600">110.9× — depth 14</text>
<text x="404" y="106" font-size="7.5" fill="#444444">before arc = 99% of time</text>
<path d="M 180.00,19.00 A 161,161 0 1,1 179.72,19.00 L 179.77,47.00 A 133,133 0 1,0 180.00,47.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 92.74,44.70 A 161,161 0 0,1 179.72,19.00 L 179.77,47.00 A 133,133 0 0,0 107.92,68.23 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,19.00 A 161,161 0 1,1 92.74,44.70 L 107.92,68.23 A 133,133 0 1,0 180.00,47.00 Z" fill="#dddddd"/>
<rect x="390" y="110" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="122" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="118" font-size="7.5" fill="#444444">mc-0002</text>
<text x="404" y="129" font-size="8.5" font-weight="500" fill="#000000">PistonStructureResolver</text>
<text x="404" y="141" font-size="8" fill="#000000" font-weight="600">1.1× — bounded ≤12</text>
<text x="404" y="152" font-size="7.5" fill="#444444">before arc = 9% of time</text>
<path d="M 180.00,52.00 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 180.00,80.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 211.82,56.02 A 128,128 0 1,1 179.78,52.00 L 179.83,80.00 A 100,100 0 1,0 204.86,83.14 Z" fill="#555555" opacity="0.75"/>
<path d="M 180.00,52.00 A 128,128 0 0,1 211.82,56.02 L 204.86,83.14 A 100,100 0 0,0 180.00,80.00 Z" fill="#dddddd"/>
<rect x="390" y="156" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="168" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="164" font-size="7.5" fill="#444444">mc-0003</text>
<text x="404" y="175" font-size="8.5" font-weight="500" fill="#000000">ExpRedstoneWireEvaluator</text>
<text x="404" y="187" font-size="8" fill="#000000" font-weight="600">~25× — N=500 wires</text>
<text x="404" y="198" font-size="7.5" fill="#444444">before arc = 96% of time</text>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="white" stroke="#cccccc" stroke-width="0.5"/>
<path d="M 180.00,85.00 A 95,95 0 1,1 179.83,85.00 L 179.88,113.00 A 67,67 0 1,0 180.00,113.00 Z" fill="#dddddd"/>
<rect x="390" y="202" width="10" height="10" fill="#555555" rx="2"/>
<rect x="390" y="214" width="10" height="3" fill="#dddddd" rx="1"/>
<text x="404" y="210" font-size="7.5" fill="#444444">mc-0004</text>
<text x="404" y="221" font-size="8.5" font-weight="500" fill="#000000">MoveThroughVillageGoal</text>
<text x="404" y="233" font-size="8" fill="#000000" font-weight="600">~1.0× — bounded ≤15</text>
<text x="404" y="244" font-size="7.5" fill="#444444">before arc = 0% of time</text>
<text x="390" y="60" font-size="8" fill="#444444" font-weight="600">DEFECTS (outer → inner ring)</text>
<rect x="20" y="352" width="12" height="12" fill="#555555" rx="2"/>
<text x="36" y="361" font-size="8" fill="#444444">BEFORE — wasted time (dark)</text>
<rect x="180" y="352" width="12" height="12" fill="#dddddd" stroke="#999" stroke-width="0.5" rx="2"/>
<text x="196" y="361" font-size="8" fill="#444444">AFTER — time with fix (light)</text>
<text x="350" y="361" font-size="7.5" fill="#444444">Arc proportional to fraction of BEFORE time.</text>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before After
Before After

View file

@ -9,156 +9,156 @@
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 1297.5)">
<title>javac_speedup</title>
<polygon fill="white" stroke="transparent" points="-36,36 -36,-1297.5 355,-1297.5 355,36 -36,36"/>
<text text-anchor="middle" x="159.5" y="-1248.7" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#555555">javac — CWE&#45;407 Speedups (real benchmarks, JDK 25)</text>
<text text-anchor="middle" x="159.5" y="-1248.7" font-family="Helvetica,sans-Serif" font-size="11.00">javac — CWE&#45;407 Speedups (real benchmarks, JDK 25)</text>
<!-- b1 -->
<g id="node1" class="node">
<title>b1</title>
<polygon fill="#fce8e8" stroke="#e88888" points="220.5,-176.5 98.5,-176.5 98.5,-119.5 220.5,-119.5 220.5,-176.5"/>
<polygon fill="white" stroke="black" stroke-width="1.5" points="219.5,-176.5 99.5,-176.5 99.5,-119.5 219.5,-119.5 219.5,-176.5"/>
<text text-anchor="middle" x="159.5" y="-164.1" font-family="Helvetica,sans-Serif" font-size="8.00">javac&#45;0001</text>
<text text-anchor="middle" x="159.5" y="-155.1" font-family="Helvetica,sans-Serif" font-size="8.00">Tarjan stack.contains()</text>
<text text-anchor="middle" x="159.5" y="-146.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(V²)</text>
<text text-anchor="middle" x="159.5" y="-137.1" font-family="Helvetica,sans-Serif" font-size="8.00">V=800: 513 µs/op</text>
<text text-anchor="middle" x="159.5" y="-128.1" font-family="Helvetica,sans-Serif" font-size="8.00">401× extra comparisons</text>
<text text-anchor="middle" x="159.5" y="-146.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Vu00b2)</text>
<text text-anchor="middle" x="159.5" y="-137.1" font-family="Helvetica,sans-Serif" font-size="8.00">V=800: 513 us/op</text>
<text text-anchor="middle" x="159.5" y="-128.1" font-family="Helvetica,sans-Serif" font-size="8.00">401x extra comparisons</text>
</g>
<!-- a1 -->
<g id="node7" class="node">
<title>a1</title>
<polygon fill="#e8f8e8" stroke="#88cc88" points="209.5,-48 109.5,-48 109.5,0 209.5,0 209.5,-48"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="209.5,-48 109.5,-48 109.5,0 209.5,0 209.5,-48"/>
<text text-anchor="middle" x="159.5" y="-35.6" font-family="Helvetica,sans-Serif" font-size="8.00">Tarjan n.active flag</text>
<text text-anchor="middle" x="159.5" y="-26.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(V+E)</text>
<text text-anchor="middle" x="159.5" y="-17.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=800: 94 µs/op</text>
<text text-anchor="middle" x="159.5" y="-8.6" font-family="Helvetica,sans-Serif" font-size="8.00">5.46× faster</text>
<text text-anchor="middle" x="159.5" y="-17.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=800: 94 us/op</text>
<text text-anchor="middle" x="159.5" y="-8.6" font-family="Helvetica,sans-Serif" font-size="8.00">5.46x faster</text>
</g>
<!-- b1&#45;&gt;a1 -->
<g id="edge1" class="edge">
<title>b1&#45;&gt;a1</title>
<path fill="none" stroke="#cc8888" stroke-width="1.2" d="M159.5,-24.43C159.5,-60.38 159.5,-61.51 159.5,-142.31"/>
<polygon fill="#cc8888" stroke="#cc8888" stroke-width="1.2" points="157.75,-142.75 159.5,-147.75 161.25,-142.75 157.75,-142.75"/>
<path fill="none" stroke="black" stroke-width="1.8" d="M159.5,-24.43C159.5,-60.38 159.5,-61.51 159.5,-142.31"/>
<polygon fill="black" stroke="black" stroke-width="1.8" points="157.75,-142.75 159.5,-147.75 161.25,-142.75 157.75,-142.75"/>
</g>
<!-- b2a -->
<g id="node2" class="node">
<title>b2a</title>
<polygon fill="#fce8e8" stroke="#e88888" stroke-width="0.4" points="220.5,-389.5 98.5,-389.5 98.5,-332.5 220.5,-332.5 220.5,-389.5"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="219.5,-389.5 99.5,-389.5 99.5,-332.5 219.5,-332.5 219.5,-389.5"/>
<text text-anchor="middle" x="159.5" y="-377.1" font-family="Helvetica,sans-Serif" font-size="8.00">javac&#45;0002a</text>
<text text-anchor="middle" x="159.5" y="-368.1" font-family="Helvetica,sans-Serif" font-size="8.00">findNode ArrayList scan</text>
<text text-anchor="middle" x="159.5" y="-359.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N²)</text>
<text text-anchor="middle" x="159.5" y="-350.1" font-family="Helvetica,sans-Serif" font-size="8.00">N=200: 67 µs/op</text>
<text text-anchor="middle" x="159.5" y="-341.1" font-family="Helvetica,sans-Serif" font-size="8.00">101× extra comparisons</text>
<text text-anchor="middle" x="159.5" y="-359.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Nu00b2)</text>
<text text-anchor="middle" x="159.5" y="-350.1" font-family="Helvetica,sans-Serif" font-size="8.00">N=200: 67 us/op</text>
<text text-anchor="middle" x="159.5" y="-341.1" font-family="Helvetica,sans-Serif" font-size="8.00">101x extra comparisons</text>
</g>
<!-- a2a -->
<g id="node8" class="node">
<title>a2a</title>
<polygon fill="#e8f8e8" stroke="#88cc88" stroke-width="0.4" points="205.5,-261 113.5,-261 113.5,-213 205.5,-213 205.5,-261"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="205.5,-261 113.5,-261 113.5,-213 205.5,-213 205.5,-261"/>
<text text-anchor="middle" x="159.5" y="-248.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashMap lookup</text>
<text text-anchor="middle" x="159.5" y="-239.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1)</text>
<text text-anchor="middle" x="159.5" y="-230.6" font-family="Helvetica,sans-Serif" font-size="8.00">N=200: 10 µs/op</text>
<text text-anchor="middle" x="159.5" y="-221.6" font-family="Helvetica,sans-Serif" font-size="8.00">6.9× faster</text>
<text text-anchor="middle" x="159.5" y="-230.6" font-family="Helvetica,sans-Serif" font-size="8.00">N=200: 10 us/op</text>
<text text-anchor="middle" x="159.5" y="-221.6" font-family="Helvetica,sans-Serif" font-size="8.00">6.9x faster</text>
</g>
<!-- b2a&#45;&gt;a2a -->
<g id="edge2" class="edge">
<title>b2a&#45;&gt;a2a</title>
<path fill="none" stroke="#cc8888" stroke-width="0.8" d="M159.5,-237.43C159.5,-273.38 159.5,-274.51 159.5,-355.31"/>
<polygon fill="#cc8888" stroke="#cc8888" stroke-width="0.8" points="157.75,-355.75 159.5,-360.75 161.25,-355.75 157.75,-355.75"/>
<path fill="none" stroke="black" stroke-width="1.4" d="M159.5,-237.43C159.5,-273.38 159.5,-274.51 159.5,-355.31"/>
<polygon fill="black" stroke="black" stroke-width="1.4" points="157.75,-355.75 159.5,-360.75 161.25,-355.75 157.75,-355.75"/>
</g>
<!-- b2b -->
<g id="node3" class="node">
<title>b2b</title>
<polygon fill="#fce8e8" stroke="#e88888" stroke-width="0.4" points="223,-602.5 96,-602.5 96,-545.5 223,-545.5 223,-602.5"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="223,-602.5 96,-602.5 96,-545.5 223,-545.5 223,-602.5"/>
<text text-anchor="middle" x="159.5" y="-590.1" font-family="Helvetica,sans-Serif" font-size="8.00">javac&#45;0002b</text>
<text text-anchor="middle" x="159.5" y="-581.1" font-family="Helvetica,sans-Serif" font-size="8.00">closure uncached DFS</text>
<text text-anchor="middle" x="159.5" y="-572.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(V·K)</text>
<text text-anchor="middle" x="159.5" y="-563.1" font-family="Helvetica,sans-Serif" font-size="8.00">V=100,K=100: 230 µs/op</text>
<text text-anchor="middle" x="159.5" y="-554.1" font-family="Helvetica,sans-Serif" font-size="8.00">50× extra work</text>
<text text-anchor="middle" x="159.5" y="-572.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Vu00b7K)</text>
<text text-anchor="middle" x="159.5" y="-563.1" font-family="Helvetica,sans-Serif" font-size="8.00">V=100,K=100: 230 us/op</text>
<text text-anchor="middle" x="159.5" y="-554.1" font-family="Helvetica,sans-Serif" font-size="8.00">50x extra work</text>
</g>
<!-- a2b -->
<g id="node9" class="node">
<title>a2b</title>
<polygon fill="#e8f8e8" stroke="#88cc88" stroke-width="0.4" points="205.5,-474 113.5,-474 113.5,-426 205.5,-426 205.5,-474"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="205.5,-474 113.5,-474 113.5,-426 205.5,-426 205.5,-474"/>
<text text-anchor="middle" x="159.5" y="-461.6" font-family="Helvetica,sans-Serif" font-size="8.00">cached DFS</text>
<text text-anchor="middle" x="159.5" y="-452.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(V+E)</text>
<text text-anchor="middle" x="159.5" y="-443.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=100: 11 µs/op</text>
<text text-anchor="middle" x="159.5" y="-434.6" font-family="Helvetica,sans-Serif" font-size="8.00">20.9× faster</text>
<text text-anchor="middle" x="159.5" y="-443.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=100: 11 us/op</text>
<text text-anchor="middle" x="159.5" y="-434.6" font-family="Helvetica,sans-Serif" font-size="8.00">20.9x faster</text>
</g>
<!-- b2b&#45;&gt;a2b -->
<g id="edge3" class="edge">
<title>b2b&#45;&gt;a2b</title>
<path fill="none" stroke="#cc8888" stroke-width="1.4" d="M159.5,-450.43C159.5,-486.38 159.5,-487.51 159.5,-568.31"/>
<polygon fill="#cc8888" stroke="#cc8888" stroke-width="1.4" points="157.75,-568.75 159.5,-573.75 161.25,-568.75 157.75,-568.75"/>
<path fill="none" stroke="black" stroke-width="2.5" d="M159.5,-450.43C159.5,-486.38 159.5,-487.51 159.5,-568.31"/>
<polygon fill="black" stroke="black" stroke-width="2.5" points="157.75,-568.75 159.5,-573.75 161.25,-568.75 157.75,-568.75"/>
</g>
<!-- b3 -->
<g id="node4" class="node">
<title>b3</title>
<polygon fill="#fce8e8" stroke="#e88888" stroke-width="0.4" points="229.5,-815.5 89.5,-815.5 89.5,-758.5 229.5,-758.5 229.5,-815.5"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="229.5,-815.5 89.5,-815.5 89.5,-758.5 229.5,-758.5 229.5,-815.5"/>
<text text-anchor="middle" x="159.5" y="-803.1" font-family="Helvetica,sans-Serif" font-size="8.00">javac&#45;0003</text>
<text text-anchor="middle" x="159.5" y="-794.1" font-family="Helvetica,sans-Serif" font-size="8.00">TopoSorter Deque.contains()</text>
<text text-anchor="middle" x="159.5" y="-785.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(V²)</text>
<text text-anchor="middle" x="159.5" y="-776.1" font-family="Helvetica,sans-Serif" font-size="8.00">V=200: 60 µs/op</text>
<text text-anchor="middle" x="159.5" y="-767.1" font-family="Helvetica,sans-Serif" font-size="8.00">100× extra comparisons</text>
<text text-anchor="middle" x="159.5" y="-785.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Vu00b2)</text>
<text text-anchor="middle" x="159.5" y="-776.1" font-family="Helvetica,sans-Serif" font-size="8.00">V=200: 60 us/op</text>
<text text-anchor="middle" x="159.5" y="-767.1" font-family="Helvetica,sans-Serif" font-size="8.00">100x extra comparisons</text>
</g>
<!-- a3 -->
<g id="node10" class="node">
<title>a3</title>
<polygon fill="#e8f8e8" stroke="#88cc88" stroke-width="0.4" points="210,-687 109,-687 109,-639 210,-639 210,-687"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="210,-687 109,-687 109,-639 210,-639 210,-687"/>
<text text-anchor="middle" x="159.5" y="-674.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet.contains()</text>
<text text-anchor="middle" x="159.5" y="-665.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1)</text>
<text text-anchor="middle" x="159.5" y="-656.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=200: 40 µs/op</text>
<text text-anchor="middle" x="159.5" y="-647.6" font-family="Helvetica,sans-Serif" font-size="8.00">1.5× faster</text>
<text text-anchor="middle" x="159.5" y="-656.6" font-family="Helvetica,sans-Serif" font-size="8.00">V=200: 40 us/op</text>
<text text-anchor="middle" x="159.5" y="-647.6" font-family="Helvetica,sans-Serif" font-size="8.00">1.5x faster</text>
</g>
<!-- b3&#45;&gt;a3 -->
<g id="edge4" class="edge">
<title>b3&#45;&gt;a3</title>
<path fill="none" stroke="#bbbbbb" stroke-width="0.8" d="M159.5,-663.25C159.5,-745.08 159.5,-749.58 159.5,-781.24"/>
<polygon fill="#bbbbbb" stroke="#bbbbbb" stroke-width="0.8" points="157.75,-781.57 159.5,-786.57 161.25,-781.57 157.75,-781.57"/>
<path fill="none" stroke="black" stroke-width="0.6" d="M159.5,-663.25C159.5,-745.08 159.5,-749.58 159.5,-781.24"/>
<polygon fill="black" stroke="black" stroke-width="0.6" points="157.75,-781.57 159.5,-786.57 161.25,-781.57 157.75,-781.57"/>
</g>
<!-- b4 -->
<g id="node5" class="node">
<title>b4</title>
<polygon fill="#fce8e8" stroke="#e88888" stroke-width="0.4" points="231.5,-1028.5 87.5,-1028.5 87.5,-971.5 231.5,-971.5 231.5,-1028.5"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="231.5,-1028.5 87.5,-1028.5 87.5,-971.5 231.5,-971.5 231.5,-1028.5"/>
<text text-anchor="middle" x="159.5" y="-1016.1" font-family="Helvetica,sans-Serif" font-size="8.00">javac&#45;0004</text>
<text text-anchor="middle" x="159.5" y="-1007.1" font-family="Helvetica,sans-Serif" font-size="8.00">DependencyList.add contains</text>
<text text-anchor="middle" x="159.5" y="-998.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N²)</text>
<text text-anchor="middle" x="159.5" y="-989.1" font-family="Helvetica,sans-Serif" font-size="8.00">M=200: 15 µs/op</text>
<text text-anchor="middle" x="159.5" y="-980.1" font-family="Helvetica,sans-Serif" font-size="8.00">100× extra comparisons</text>
<text text-anchor="middle" x="159.5" y="-998.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Nu00b2)</text>
<text text-anchor="middle" x="159.5" y="-989.1" font-family="Helvetica,sans-Serif" font-size="8.00">M=200: 15 us/op</text>
<text text-anchor="middle" x="159.5" y="-980.1" font-family="Helvetica,sans-Serif" font-size="8.00">100x extra comparisons</text>
</g>
<!-- a4 -->
<g id="node11" class="node">
<title>a4</title>
<polygon fill="#e8f8e8" stroke="#88cc88" stroke-width="0.4" points="213.5,-900 105.5,-900 105.5,-852 213.5,-852 213.5,-900"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="213.5,-900 105.5,-900 105.5,-852 213.5,-852 213.5,-900"/>
<text text-anchor="middle" x="159.5" y="-887.6" font-family="Helvetica,sans-Serif" font-size="8.00">LinkedHashSet.add()</text>
<text text-anchor="middle" x="159.5" y="-878.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1)</text>
<text text-anchor="middle" x="159.5" y="-869.6" font-family="Helvetica,sans-Serif" font-size="8.00">M=200: 4 µs/op</text>
<text text-anchor="middle" x="159.5" y="-860.6" font-family="Helvetica,sans-Serif" font-size="8.00">4.3× faster</text>
<text text-anchor="middle" x="159.5" y="-869.6" font-family="Helvetica,sans-Serif" font-size="8.00">M=200: 4 us/op</text>
<text text-anchor="middle" x="159.5" y="-860.6" font-family="Helvetica,sans-Serif" font-size="8.00">4.3x faster</text>
</g>
<!-- b4&#45;&gt;a4 -->
<g id="edge5" class="edge">
<title>b4&#45;&gt;a4</title>
<path fill="none" stroke="#cc8888" stroke-width="0.8" d="M159.5,-876.25C159.5,-958.08 159.5,-962.58 159.5,-994.24"/>
<polygon fill="#cc8888" stroke="#cc8888" stroke-width="0.8" points="157.75,-994.57 159.5,-999.57 161.25,-994.57 157.75,-994.57"/>
<path fill="none" stroke="black" stroke-width="1.2" d="M159.5,-876.25C159.5,-958.08 159.5,-962.58 159.5,-994.24"/>
<polygon fill="black" stroke="black" stroke-width="1.2" points="157.75,-994.57 159.5,-999.57 161.25,-994.57 157.75,-994.57"/>
</g>
<!-- b5 -->
<g id="node6" class="node">
<title>b5</title>
<polygon fill="#fce8e8" stroke="#e88888" stroke-width="0.4" points="220.5,-1241.5 98.5,-1241.5 98.5,-1184.5 220.5,-1184.5 220.5,-1241.5"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="219.5,-1241.5 99.5,-1241.5 99.5,-1184.5 219.5,-1184.5 219.5,-1241.5"/>
<text text-anchor="middle" x="159.5" y="-1229.1" font-family="Helvetica,sans-Serif" font-size="8.00">javac&#45;0005</text>
<text text-anchor="middle" x="159.5" y="-1220.1" font-family="Helvetica,sans-Serif" font-size="8.00">BoundSet containsAll</text>
<text text-anchor="middle" x="159.5" y="-1211.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(B²)</text>
<text text-anchor="middle" x="159.5" y="-1202.1" font-family="Helvetica,sans-Serif" font-size="8.00">B=100: 11 µs/op</text>
<text text-anchor="middle" x="159.5" y="-1193.1" font-family="Helvetica,sans-Serif" font-size="8.00">101× extra comparisons</text>
<text text-anchor="middle" x="159.5" y="-1211.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Bu00b2)</text>
<text text-anchor="middle" x="159.5" y="-1202.1" font-family="Helvetica,sans-Serif" font-size="8.00">B=100: 11 us/op</text>
<text text-anchor="middle" x="159.5" y="-1193.1" font-family="Helvetica,sans-Serif" font-size="8.00">101x extra comparisons</text>
</g>
<!-- a5 -->
<g id="node12" class="node">
<title>a5</title>
<polygon fill="#e8f8e8" stroke="#88cc88" stroke-width="0.4" points="202.5,-1113 116.5,-1113 116.5,-1065 202.5,-1065 202.5,-1113"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="202.5,-1113 116.5,-1113 116.5,-1065 202.5,-1065 202.5,-1113"/>
<text text-anchor="middle" x="159.5" y="-1100.6" font-family="Helvetica,sans-Serif" font-size="8.00">Set.equals()</text>
<text text-anchor="middle" x="159.5" y="-1091.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(B)</text>
<text text-anchor="middle" x="159.5" y="-1082.6" font-family="Helvetica,sans-Serif" font-size="8.00">B=100: 5 µs/op</text>
<text text-anchor="middle" x="159.5" y="-1073.6" font-family="Helvetica,sans-Serif" font-size="8.00">2.4× faster</text>
<text text-anchor="middle" x="159.5" y="-1082.6" font-family="Helvetica,sans-Serif" font-size="8.00">B=100: 5 us/op</text>
<text text-anchor="middle" x="159.5" y="-1073.6" font-family="Helvetica,sans-Serif" font-size="8.00">2.4x faster</text>
</g>
<!-- b5&#45;&gt;a5 -->
<g id="edge6" class="edge">
<title>b5&#45;&gt;a5</title>
<path fill="none" stroke="#cc8888" stroke-width="0.8" d="M159.5,-1089.25C159.5,-1171.08 159.5,-1175.58 159.5,-1207.24"/>
<polygon fill="#cc8888" stroke="#cc8888" stroke-width="0.8" points="157.75,-1207.57 159.5,-1212.57 161.25,-1207.57 157.75,-1207.57"/>
<path fill="none" stroke="black" stroke-width="0.8" d="M159.5,-1089.25C159.5,-1171.08 159.5,-1175.58 159.5,-1207.24"/>
<polygon fill="black" stroke="black" stroke-width="0.8" points="157.75,-1207.57 159.5,-1212.57 161.25,-1207.57 157.75,-1207.57"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

@ -4,164 +4,164 @@
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: mc_client_speedup Pages: 1 -->
<svg width="580pt" height="899pt"
viewBox="0.00 0.00 580.00 898.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="579pt" height="899pt"
viewBox="0.00 0.00 579.00 898.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 862.5)">
<title>mc_client_speedup</title>
<polygon fill="white" stroke="transparent" points="-36,36 -36,-862.5 544,-862.5 544,36 -36,36"/>
<text text-anchor="middle" x="220" y="-813.7" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#555555">Minecraft Client — CWE&#45;407 Impact (shared defective classes, single&#45;player)</text>
<polygon fill="white" stroke="transparent" points="-36,36 -36,-862.5 543,-862.5 543,36 -36,36"/>
<text text-anchor="middle" x="220" y="-813.7" font-family="Helvetica,sans-Serif" font-size="11.00">Minecraft Client — CWE&#45;407 Impact (shared defective classes, single&#45;player)</text>
<!-- worldload -->
<g id="node1" class="node">
<title>worldload</title>
<polygon fill="#f0f0f8" stroke="#9999cc" stroke-width="0.8" points="133.5,-179.5 57.5,-179.5 57.5,-143.5 133.5,-143.5 133.5,-179.5"/>
<text text-anchor="middle" x="95.5" y="-164.1" font-family="Helvetica,sans-Serif" font-size="8.00">Single&#45;Player</text>
<text text-anchor="middle" x="95.5" y="-155.1" font-family="Helvetica,sans-Serif" font-size="8.00">World Load</text>
<polygon fill="white" stroke="black" points="133,-179.5 57,-179.5 57,-143.5 133,-143.5 133,-179.5"/>
<text text-anchor="middle" x="95" y="-164.1" font-family="Helvetica,sans-Serif" font-size="8.00">Single&#45;Player</text>
<text text-anchor="middle" x="95" y="-155.1" font-family="Helvetica,sans-Serif" font-size="8.00">World Load</text>
</g>
<!-- b1 -->
<g id="node3" class="node">
<title>b1</title>
<polygon fill="#fce8e8" stroke="#e05555" stroke-width="1.4" points="490.5,-194.5 352.5,-194.5 352.5,-128.5 490.5,-128.5 490.5,-194.5"/>
<text text-anchor="middle" x="421.5" y="-182.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0001</text>
<text text-anchor="middle" x="421.5" y="-173.1" font-family="Helvetica,sans-Serif" font-size="8.00">DependencySorter.isCyclic</text>
<text text-anchor="middle" x="421.5" y="-164.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(E^D) — tag graph on load</text>
<text text-anchor="middle" x="421.5" y="-155.1" font-family="Helvetica,sans-Serif" font-size="8.00">Depth 14: 7,432 µs/op</text>
<text text-anchor="middle" x="421.5" y="-146.1" font-family="Helvetica,sans-Serif" font-size="8.00">Freezes world load screen</text>
<text text-anchor="middle" x="421.5" y="-137.1" font-family="Helvetica,sans-Serif" font-size="8.00">on modpacks</text>
<polygon fill="white" stroke="black" stroke-width="2" points="489.5,-194.5 351.5,-194.5 351.5,-128.5 489.5,-128.5 489.5,-194.5"/>
<text text-anchor="middle" x="420.5" y="-182.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0001</text>
<text text-anchor="middle" x="420.5" y="-173.1" font-family="Helvetica,sans-Serif" font-size="8.00">DependencySorter.isCyclic</text>
<text text-anchor="middle" x="420.5" y="-164.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(E^D) — tag graph on load</text>
<text text-anchor="middle" x="420.5" y="-155.1" font-family="Helvetica,sans-Serif" font-size="8.00">Depth 14: 7,432 us/op</text>
<text text-anchor="middle" x="420.5" y="-146.1" font-family="Helvetica,sans-Serif" font-size="8.00">Freezes world load screen</text>
<text text-anchor="middle" x="420.5" y="-137.1" font-family="Helvetica,sans-Serif" font-size="8.00">on modpacks</text>
</g>
<!-- worldload&#45;&gt;b1 -->
<g id="edge1" class="edge">
<title>worldload&#45;&gt;b1</title>
<path fill="none" stroke="#e88888" d="M133.59,-146.45C235.58,-106.64 263.83,-101.95 347.31,-132.4"/>
<polygon fill="#e88888" stroke="#e88888" points="347.07,-134.17 352.36,-134.26 348.28,-130.89 347.07,-134.17"/>
<text text-anchor="middle" x="263" y="-163.9" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#888888">tag resolution</text>
<path fill="none" stroke="black" stroke-width="1.5" d="M133.02,-146.48C234.81,-106.72 263.01,-102.04 346.39,-132.44"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="346.15,-134.21 351.44,-134.3 347.35,-130.93 346.15,-134.21"/>
<text text-anchor="middle" x="262" y="-163.9" font-family="Helvetica,sans-Serif" font-size="7.00">tag resolution</text>
</g>
<!-- gameplay -->
<g id="node2" class="node">
<title>gameplay</title>
<polygon fill="#f0f0f8" stroke="#9999cc" stroke-width="0.4" points="139,-596.5 52,-596.5 52,-560.5 139,-560.5 139,-596.5"/>
<text text-anchor="middle" x="95.5" y="-581.1" font-family="Helvetica,sans-Serif" font-size="8.00">In&#45;Game</text>
<text text-anchor="middle" x="95.5" y="-572.1" font-family="Helvetica,sans-Serif" font-size="8.00">(active session)</text>
<polygon fill="white" stroke="black" stroke-width="0.8" points="138.5,-596.5 51.5,-596.5 51.5,-560.5 138.5,-560.5 138.5,-596.5"/>
<text text-anchor="middle" x="95" y="-581.1" font-family="Helvetica,sans-Serif" font-size="8.00">In&#45;Game</text>
<text text-anchor="middle" x="95" y="-572.1" font-family="Helvetica,sans-Serif" font-size="8.00">(active session)</text>
</g>
<!-- b2 -->
<g id="node4" class="node">
<title>b2</title>
<polygon fill="#f8f8f8" stroke="#cccccc" stroke-width="0.4" points="481.5,-806.5 361.5,-806.5 361.5,-758.5 481.5,-758.5 481.5,-806.5"/>
<text text-anchor="middle" x="421.5" y="-794.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0002</text>
<text text-anchor="middle" x="421.5" y="-785.1" font-family="Helvetica,sans-Serif" font-size="8.00">PistonStructureResolver</text>
<text text-anchor="middle" x="421.5" y="-776.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(P²) piston activation</text>
<text text-anchor="middle" x="421.5" y="-767.1" font-family="Helvetica,sans-Serif" font-size="8.00">P12, minor</text>
<polygon fill="white" stroke="black" stroke-width="0.6" points="488.5,-806.5 352.5,-806.5 352.5,-758.5 488.5,-758.5 488.5,-806.5"/>
<text text-anchor="middle" x="420.5" y="-794.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0002</text>
<text text-anchor="middle" x="420.5" y="-785.1" font-family="Helvetica,sans-Serif" font-size="8.00">PistonStructureResolver</text>
<text text-anchor="middle" x="420.5" y="-776.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Pu00b2) piston activation</text>
<text text-anchor="middle" x="420.5" y="-767.1" font-family="Helvetica,sans-Serif" font-size="8.00">P&lt;=12, minor</text>
</g>
<!-- gameplay&#45;&gt;b2 -->
<g id="edge2" class="edge">
<title>gameplay&#45;&gt;b2</title>
<path fill="none" stroke="#cccccc" stroke-width="0.8" d="M112.23,-596.71C236.07,-731.46 259.95,-753.83 356.4,-771.82"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.8" points="356.11,-773.54 361.34,-772.72 356.74,-770.1 356.11,-773.54"/>
<text text-anchor="middle" x="263" y="-706.9" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#888888">piston use</text>
<path fill="none" stroke="black" stroke-width="0.5" d="M111.7,-596.71C231.66,-727.43 257.64,-752.34 347.15,-770.18"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="347.05,-771.94 352.29,-771.18 347.72,-768.51 347.05,-771.94"/>
<text text-anchor="middle" x="262" y="-706.9" font-family="Helvetica,sans-Serif" font-size="7.00">piston use</text>
</g>
<!-- b3 -->
<g id="node5" class="node">
<title>b3</title>
<polygon fill="#fff8e8" stroke="#ddcc66" points="508,-611.5 335,-611.5 335,-545.5 508,-545.5 508,-611.5"/>
<text text-anchor="middle" x="421.5" y="-599.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0003</text>
<text text-anchor="middle" x="421.5" y="-590.1" font-family="Helvetica,sans-Serif" font-size="8.00">ExperimentalRedstoneWireEvaluator</text>
<text text-anchor="middle" x="421.5" y="-581.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N²) — blocks game thread</text>
<text text-anchor="middle" x="421.5" y="-572.1" font-family="Helvetica,sans-Serif" font-size="8.00">Client experiences lag spikes</text>
<text text-anchor="middle" x="421.5" y="-563.1" font-family="Helvetica,sans-Serif" font-size="8.00">on large redstone builds</text>
<text text-anchor="middle" x="421.5" y="-554.1" font-family="Helvetica,sans-Serif" font-size="8.00">(experimental flag)</text>
<polygon fill="white" stroke="black" stroke-width="1.2" points="507,-611.5 334,-611.5 334,-545.5 507,-545.5 507,-611.5"/>
<text text-anchor="middle" x="420.5" y="-599.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0003</text>
<text text-anchor="middle" x="420.5" y="-590.1" font-family="Helvetica,sans-Serif" font-size="8.00">ExperimentalRedstoneWireEvaluator</text>
<text text-anchor="middle" x="420.5" y="-581.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Nu00b2) — blocks game thread</text>
<text text-anchor="middle" x="420.5" y="-572.1" font-family="Helvetica,sans-Serif" font-size="8.00">Client experiences lag spikes</text>
<text text-anchor="middle" x="420.5" y="-563.1" font-family="Helvetica,sans-Serif" font-size="8.00">on large redstone builds</text>
<text text-anchor="middle" x="420.5" y="-554.1" font-family="Helvetica,sans-Serif" font-size="8.00">(experimental flag)</text>
</g>
<!-- gameplay&#45;&gt;b3 -->
<g id="edge3" class="edge">
<title>gameplay&#45;&gt;b3</title>
<path fill="none" stroke="#ddcc66" stroke-width="0.8" d="M139.34,-595.73C230.37,-630.94 261.55,-636.77 331.47,-613.25"/>
<polygon fill="#ddcc66" stroke="#ddcc66" stroke-width="0.8" points="332.41,-614.78 336.57,-611.5 331.28,-611.46 332.41,-614.78"/>
<text text-anchor="middle" x="263" y="-580.9" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#888888">redstone circuit</text>
<path fill="none" stroke="black" d="M138.74,-595.7C229.47,-630.81 260.63,-636.67 330.29,-613.29"/>
<polygon fill="black" stroke="black" points="331.21,-614.82 335.37,-611.55 330.08,-611.51 331.21,-614.82"/>
<text text-anchor="middle" x="262" y="-580.9" font-family="Helvetica,sans-Serif" font-size="7.00">redstone circuit</text>
</g>
<!-- b4 -->
<g id="node6" class="node">
<title>b4</title>
<polygon fill="#f8f8f8" stroke="#cccccc" stroke-width="0.4" points="484,-389.5 359,-389.5 359,-341.5 484,-341.5 484,-389.5"/>
<text text-anchor="middle" x="421.5" y="-377.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0004</text>
<text text-anchor="middle" x="421.5" y="-368.1" font-family="Helvetica,sans-Serif" font-size="8.00">MoveThroughVillageGoal</text>
<text text-anchor="middle" x="421.5" y="-359.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N²) villager AI</text>
<text text-anchor="middle" x="421.5" y="-350.1" font-family="Helvetica,sans-Serif" font-size="8.00">N15, negligible</text>
<polygon fill="white" stroke="black" stroke-width="0.6" points="483,-389.5 358,-389.5 358,-341.5 483,-341.5 483,-389.5"/>
<text text-anchor="middle" x="420.5" y="-377.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0004</text>
<text text-anchor="middle" x="420.5" y="-368.1" font-family="Helvetica,sans-Serif" font-size="8.00">MoveThroughVillageGoal</text>
<text text-anchor="middle" x="420.5" y="-359.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Nu00b2) villager AI</text>
<text text-anchor="middle" x="420.5" y="-350.1" font-family="Helvetica,sans-Serif" font-size="8.00">N&lt;=15, negligible</text>
</g>
<!-- gameplay&#45;&gt;b4 -->
<g id="edge4" class="edge">
<title>gameplay&#45;&gt;b4</title>
<path fill="none" stroke="#cccccc" stroke-width="0.8" d="M139.02,-570.91C257.44,-549.44 276.51,-534.19 397.09,-393.94"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.8" points="398.76,-394.69 400.69,-389.76 396.11,-392.41 398.76,-394.69"/>
<text text-anchor="middle" x="263" y="-449.9" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#888888">villager AI</text>
<path fill="none" stroke="black" stroke-width="0.5" d="M138.79,-570.82C256.48,-549.34 275.62,-533.97 396.11,-393.91"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="397.77,-394.66 399.71,-389.73 395.12,-392.38 397.77,-394.66"/>
<text text-anchor="middle" x="262" y="-449.9" font-family="Helvetica,sans-Serif" font-size="7.00">villager AI</text>
</g>
<!-- a1 -->
<g id="node7" class="node">
<title>a1</title>
<polygon fill="#e8f8e8" stroke="#55aa55" stroke-width="1.4" points="497.5,-57 345.5,-57 345.5,0 497.5,0 497.5,-57"/>
<text text-anchor="middle" x="421.5" y="-44.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet visited set</text>
<text text-anchor="middle" x="421.5" y="-35.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(E) per call</text>
<text text-anchor="middle" x="421.5" y="-26.6" font-family="Helvetica,sans-Serif" font-size="8.00">110.9× faster world load</text>
<text text-anchor="middle" x="421.5" y="-17.6" font-family="Helvetica,sans-Serif" font-size="8.00">Modpack load: seconds ms</text>
<text text-anchor="middle" x="421.5" y="-8.6" font-family="Helvetica,sans-Serif" font-size="8.00">No stack overflow at depth 16+</text>
<polygon fill="white" stroke="black" stroke-width="0.8" points="496.5,-57 344.5,-57 344.5,0 496.5,0 496.5,-57"/>
<text text-anchor="middle" x="420.5" y="-44.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet visited set</text>
<text text-anchor="middle" x="420.5" y="-35.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(E) per call</text>
<text text-anchor="middle" x="420.5" y="-26.6" font-family="Helvetica,sans-Serif" font-size="8.00">110.9x faster world load</text>
<text text-anchor="middle" x="420.5" y="-17.6" font-family="Helvetica,sans-Serif" font-size="8.00">Modpack load: seconds &#45;&gt; ms</text>
<text text-anchor="middle" x="420.5" y="-8.6" font-family="Helvetica,sans-Serif" font-size="8.00">No stack overflow at depth 16+</text>
</g>
<!-- b1&#45;&gt;a1 -->
<g id="edge5" class="edge">
<title>b1&#45;&gt;a1</title>
<path fill="none" stroke="#cc3333" stroke-width="1.8" d="M421.65,-29C433.94,-70.76 434.15,-71.95 422.26,-156.11"/>
<polygon fill="#cc3333" stroke="#cc3333" stroke-width="1.8" points="420.5,-156.04 421.54,-161.24 423.97,-156.53 420.5,-156.04"/>
<path fill="none" stroke="black" stroke-width="2.5" d="M420.65,-29C432.91,-70.74 433.12,-71.93 421.26,-156.11"/>
<polygon fill="black" stroke="black" stroke-width="2.5" points="419.5,-156.04 420.54,-161.24 422.97,-156.53 419.5,-156.04"/>
</g>
<!-- a2 -->
<g id="node8" class="node">
<title>a2</title>
<polygon fill="#f5fff5" stroke="#aaccaa" stroke-width="0.4" points="472,-687 371,-687 371,-648 472,-648 472,-687"/>
<text text-anchor="middle" x="421.5" y="-674.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet toPushSet</text>
<text text-anchor="middle" x="421.5" y="-665.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) per check</text>
<text text-anchor="middle" x="421.5" y="-656.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.1× (bounded)</text>
<polygon fill="white" stroke="black" stroke-width="0.8" points="471,-687 370,-687 370,-648 471,-648 471,-687"/>
<text text-anchor="middle" x="420.5" y="-674.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet toPushSet</text>
<text text-anchor="middle" x="420.5" y="-665.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) per check</text>
<text text-anchor="middle" x="420.5" y="-656.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.1x (bounded)</text>
</g>
<!-- b2&#45;&gt;a2 -->
<g id="edge6" class="edge">
<title>b2&#45;&gt;a2</title>
<path fill="none" stroke="#cccccc" stroke-width="0.8" d="M421.56,-667.95C431.59,-741.48 432.07,-745.27 423.03,-777.15"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.8" points="421.31,-776.78 421.62,-782.07 424.68,-777.74 421.31,-776.78"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M420.56,-667.95C430.56,-741.49 431.05,-745.28 422.02,-777.15"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="420.31,-776.78 420.62,-782.07 423.68,-777.74 420.31,-776.78"/>
</g>
<!-- a3 -->
<g id="node9" class="node">
<title>a3</title>
<polygon fill="#e8f8e8" stroke="#88cc88" points="480,-473.5 363,-473.5 363,-425.5 480,-425.5 480,-473.5"/>
<text text-anchor="middle" x="421.5" y="-461.1" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet inFrontier sets</text>
<text text-anchor="middle" x="421.5" y="-452.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N) BFS total</text>
<text text-anchor="middle" x="421.5" y="-443.1" font-family="Helvetica,sans-Serif" font-size="8.00">Eliminates redstone</text>
<text text-anchor="middle" x="421.5" y="-434.1" font-family="Helvetica,sans-Serif" font-size="8.00">lag spikes</text>
<polygon fill="white" stroke="black" stroke-width="0.8" points="479,-473.5 362,-473.5 362,-425.5 479,-425.5 479,-473.5"/>
<text text-anchor="middle" x="420.5" y="-461.1" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet inFrontier sets</text>
<text text-anchor="middle" x="420.5" y="-452.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N) BFS total</text>
<text text-anchor="middle" x="420.5" y="-443.1" font-family="Helvetica,sans-Serif" font-size="8.00">Eliminates redstone</text>
<text text-anchor="middle" x="420.5" y="-434.1" font-family="Helvetica,sans-Serif" font-size="8.00">lag spikes</text>
</g>
<!-- b3&#45;&gt;a3 -->
<g id="edge7" class="edge">
<title>b3&#45;&gt;a3</title>
<path fill="none" stroke="#cc9933" d="M421.63,-449.96C442.27,-525.48 442.96,-528.22 423.68,-573.4"/>
<polygon fill="#cc9933" stroke="#cc9933" points="421.98,-572.92 421.63,-578.21 425.2,-574.3 421.98,-572.92"/>
<path fill="none" stroke="black" stroke-width="1.2" d="M420.63,-449.96C441.25,-525.51 441.94,-528.25 422.68,-573.4"/>
<polygon fill="black" stroke="black" stroke-width="1.2" points="420.98,-572.92 420.63,-578.21 424.2,-574.3 420.98,-572.92"/>
</g>
<!-- a4 -->
<g id="node10" class="node">
<title>a4</title>
<polygon fill="#f5fff5" stroke="#aaccaa" stroke-width="0.4" points="471.5,-270 371.5,-270 371.5,-231 471.5,-231 471.5,-270"/>
<text text-anchor="middle" x="421.5" y="-257.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet visitedSet</text>
<text text-anchor="middle" x="421.5" y="-248.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) lookup</text>
<text text-anchor="middle" x="421.5" y="-239.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.0× (bounded)</text>
<polygon fill="white" stroke="black" stroke-width="0.8" points="470.5,-270 370.5,-270 370.5,-231 470.5,-231 470.5,-270"/>
<text text-anchor="middle" x="420.5" y="-257.6" font-family="Helvetica,sans-Serif" font-size="8.00">HashSet visitedSet</text>
<text text-anchor="middle" x="420.5" y="-248.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) lookup</text>
<text text-anchor="middle" x="420.5" y="-239.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.0x (bounded)</text>
</g>
<!-- b4&#45;&gt;a4 -->
<g id="edge8" class="edge">
<title>b4&#45;&gt;a4</title>
<path fill="none" stroke="#cccccc" stroke-width="0.8" d="M421.62,-250.77C440.95,-295.38 441.44,-296.72 423.09,-360.02"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.8" points="421.33,-359.81 421.62,-365.1 424.69,-360.78 421.33,-359.81"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M420.62,-250.77C439.94,-295.35 440.43,-296.7 422.09,-360.02"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="420.33,-359.81 420.62,-365.1 423.69,-360.78 420.33,-359.81"/>
</g>
<!-- note -->
<g id="node11" class="node">
<title>note</title>
<polygon fill="#f8f8ff" stroke="#bbbbcc" stroke-width="0.4" points="185,-684.5 0,-684.5 0,-632.5 191,-632.5 191,-678.5 185,-684.5"/>
<polyline fill="none" stroke="#bbbbcc" stroke-width="0.4" points="185,-684.5 185,-678.5 "/>
<polyline fill="none" stroke="#bbbbcc" stroke-width="0.4" points="191,-678.5 185,-678.5 "/>
<text text-anchor="middle" x="95.5" y="-672.5" font-family="Helvetica,sans-Serif" font-size="7.50">Client note: same JARs, same defects.</text>
<text text-anchor="middle" x="95.5" y="-664.5" font-family="Helvetica,sans-Serif" font-size="7.50">Modpack players loading 1000+ cross&#45;mod</text>
<text text-anchor="middle" x="95.5" y="-656.5" font-family="Helvetica,sans-Serif" font-size="7.50">tags at diamond depth 814 experience</text>
<text text-anchor="middle" x="95.5" y="-648.5" font-family="Helvetica,sans-Serif" font-size="7.50">world load times of 1060s on slow hardware.</text>
<text text-anchor="middle" x="95.5" y="-640.5" font-family="Helvetica,sans-Serif" font-size="7.50">Patch eliminates the exponential growth.</text>
<polygon fill="white" stroke="black" stroke-width="0.5" points="184,-684.5 0,-684.5 0,-632.5 190,-632.5 190,-678.5 184,-684.5"/>
<polyline fill="none" stroke="black" stroke-width="0.5" points="184,-684.5 184,-678.5 "/>
<polyline fill="none" stroke="black" stroke-width="0.5" points="190,-678.5 184,-678.5 "/>
<text text-anchor="middle" x="95" y="-672.5" font-family="Helvetica,sans-Serif" font-size="7.50">Client note: same JARs, same defects.</text>
<text text-anchor="middle" x="95" y="-664.5" font-family="Helvetica,sans-Serif" font-size="7.50">Modpack players loading 1000+ cross&#45;mod</text>
<text text-anchor="middle" x="95" y="-656.5" font-family="Helvetica,sans-Serif" font-size="7.50">tags at diamond depth 8&#45;14 experience</text>
<text text-anchor="middle" x="95" y="-648.5" font-family="Helvetica,sans-Serif" font-size="7.50">world load times of 10&#45;60s on slow hardware.</text>
<text text-anchor="middle" x="95" y="-640.5" font-family="Helvetica,sans-Serif" font-size="7.50">Patch eliminates the exponential growth.</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

@ -4,131 +4,131 @@
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: mc_gameloop Pages: 1 -->
<svg width="1182pt" height="596pt"
viewBox="0.00 0.00 1182.10 595.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="1384pt" height="596pt"
viewBox="0.00 0.00 1384.10 595.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 566.8)">
<title>mc_gameloop</title>
<polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-566.8 1153.3,-566.8 1153.3,28.8 -28.8,28.8"/>
<text text-anchor="middle" x="170" y="-525.2" font-family="Helvetica,sans-Serif" font-size="11.00" fill="#555555">Minecraft Server Tick — Known Slow Paths (20 TPS target)</text>
<polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-566.8 1355.3,-566.8 1355.3,28.8 -28.8,28.8"/>
<text text-anchor="middle" x="170" y="-525.2" font-family="Helvetica,sans-Serif" font-size="11.00">Minecraft Server Tick — Known Slow Paths (20 TPS target)</text>
<g id="clust1" class="cluster">
<title>cluster_legend</title>
<polygon fill="#fafafa" stroke="#eeeeee" stroke-width="0.3" points="676.5,-441 676.5,-510 1116.5,-510 1116.5,-441 676.5,-441"/>
<text text-anchor="middle" x="700" y="-499.6" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#555555">Legend</text>
<polygon fill="white" stroke="black" stroke-width="0.5" stroke-dasharray="1,5" points="676.5,-441 676.5,-510 1318.5,-510 1318.5,-441 676.5,-441"/>
<text text-anchor="middle" x="692" y="-499.6" font-family="Helvetica,sans-Serif" font-size="8.00">Key</text>
</g>
<!-- tick -->
<g id="node1" class="node">
<title>tick</title>
<polygon fill="#f0f0f8" stroke="#9999cc" stroke-width="0.8" points="385,-485 280,-485 280,-449 385,-449 385,-485"/>
<polygon fill="white" stroke="black" stroke-width="1.5" points="385,-485 280,-485 280,-449 385,-449 385,-485"/>
<text text-anchor="middle" x="332.5" y="-469.6" font-family="Helvetica,sans-Serif" font-size="8.00">MinecraftServer.tick()</text>
<text text-anchor="middle" x="332.5" y="-460.6" font-family="Helvetica,sans-Serif" font-size="8.00">50ms budget / tick</text>
</g>
<!-- world -->
<g id="node2" class="node">
<title>world</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="318,-393 229,-393 229,-357 318,-357 318,-393"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="318,-393 229,-393 229,-357 318,-357 318,-393"/>
<text text-anchor="middle" x="273.5" y="-373.1" font-family="Helvetica,sans-Serif" font-size="8.00">ServerLevel.tick()</text>
</g>
<!-- tick&#45;&gt;world -->
<g id="edge1" class="edge">
<title>tick&#45;&gt;world</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M307.96,-448.95C288.49,-433.59 283.62,-424.38 277.86,-397.16"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="279.18,-396.64 277,-393.01 276.44,-397.21 279.18,-396.64"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M308.75,-448.85C287.8,-431.98 282.73,-423.09 277.54,-397.25"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="278.91,-396.97 276.77,-393.31 276.16,-397.5 278.91,-396.97"/>
</g>
<!-- chunks -->
<g id="node3" class="node">
<title>chunks</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="503.5,-393 407.5,-393 407.5,-357 503.5,-357 503.5,-393"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="503.5,-393 407.5,-393 407.5,-357 503.5,-357 503.5,-393"/>
<text text-anchor="middle" x="455.5" y="-377.6" font-family="Helvetica,sans-Serif" font-size="8.00">ServerChunkCache</text>
<text text-anchor="middle" x="455.5" y="-368.6" font-family="Helvetica,sans-Serif" font-size="8.00">.tick()</text>
</g>
<!-- tick&#45;&gt;chunks -->
<g id="edge2" class="edge">
<title>tick&#45;&gt;chunks</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M360.69,-448.92C376.32,-438.33 391.15,-426.72 429.56,-395.86"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="430.62,-396.81 432.86,-393.21 428.86,-394.63 430.62,-396.81"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M353.91,-448.84C369.82,-435.71 383.79,-425.55 426.37,-395.52"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="427.3,-396.58 429.76,-393.13 425.68,-394.29 427.3,-396.58"/>
</g>
<!-- ents -->
<g id="node4" class="node">
<title>ents</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="127,-308 48,-308 48,-272 127,-272 127,-308"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="127,-308 48,-308 48,-272 127,-272 127,-308"/>
<text text-anchor="middle" x="87.5" y="-288.1" font-family="Helvetica,sans-Serif" font-size="8.00">Entity tick loop</text>
</g>
<!-- world&#45;&gt;ents -->
<g id="edge3" class="edge">
<title>world&#45;&gt;ents</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M228.84,-363.27C156.43,-343.95 138.86,-336.63 110.25,-311.21"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="110.98,-309.99 107.07,-308.36 109.11,-312.07 110.98,-309.99"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M228.75,-362.74C156.54,-342.68 138.78,-335.29 110.53,-310.9"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="111.33,-309.74 107.4,-308.16 109.49,-311.85 111.33,-309.74"/>
</g>
<!-- blocks -->
<g id="node5" class="node">
<title>blocks</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="282.5,-308 172.5,-308 172.5,-272 282.5,-272 282.5,-308"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="282.5,-308 172.5,-308 172.5,-272 282.5,-272 282.5,-308"/>
<text text-anchor="middle" x="227.5" y="-292.6" font-family="Helvetica,sans-Serif" font-size="8.00">Block tick</text>
<text text-anchor="middle" x="227.5" y="-283.6" font-family="Helvetica,sans-Serif" font-size="8.00">(random + scheduled)</text>
</g>
<!-- world&#45;&gt;blocks -->
<g id="edge4" class="edge">
<title>world&#45;&gt;blocks</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M253.76,-356.73C236.75,-340.26 232.38,-332.14 229.74,-312.23"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="231.11,-311.88 229.24,-308.08 228.33,-312.22 231.11,-311.88"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M254.32,-356.89C236.81,-339.71 232.3,-331.63 229.7,-312.2"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="231.09,-311.95 229.21,-308.15 228.31,-312.29 231.09,-311.95"/>
</g>
<!-- redst -->
<g id="node6" class="node">
<title>redst</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="389,-308 320,-308 320,-272 389,-272 389,-308"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="389,-308 320,-308 320,-272 389,-272 389,-308"/>
<text text-anchor="middle" x="354.5" y="-292.6" font-family="Helvetica,sans-Serif" font-size="8.00">Redstone</text>
<text text-anchor="middle" x="354.5" y="-283.6" font-family="Helvetica,sans-Serif" font-size="8.00">propagation</text>
</g>
<!-- world&#45;&gt;redst -->
<g id="edge5" class="edge">
<title>world&#45;&gt;redst</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M282.91,-356.89C291.8,-341.18 300.07,-332.93 328.33,-310.51"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="329.24,-311.58 331.51,-308 327.5,-309.38 329.24,-311.58"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M282.2,-356.92C290.95,-340.19 298.88,-332.08 326.67,-310.88"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="327.82,-311.76 330.16,-308.23 326.13,-309.54 327.82,-311.76"/>
</g>
<!-- chunkmap -->
<g id="node16" class="node">
<title>chunkmap</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="523,-308 418,-308 418,-272 523,-272 523,-308"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="523,-308 418,-308 418,-272 523,-272 523,-308"/>
<text text-anchor="middle" x="470.5" y="-292.6" font-family="Helvetica,sans-Serif" font-size="8.00">ChunkMap</text>
<text text-anchor="middle" x="470.5" y="-283.6" font-family="Helvetica,sans-Serif" font-size="8.00">dependency tracking</text>
</g>
<!-- chunks&#45;&gt;chunkmap -->
<g id="edge14" class="edge">
<title>chunks&#45;&gt;chunkmap</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M452.29,-356.81C450.69,-343.51 452.72,-334.88 461.74,-311.83"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="463.09,-312.24 463.25,-308 460.48,-311.21 463.09,-312.24"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M451.45,-356.83C448.57,-341.09 450.2,-332.9 459.92,-311.93"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="461.26,-312.37 461.69,-308.16 458.73,-311.18 461.26,-312.37"/>
</g>
<!-- ai -->
<g id="node11" class="node">
<title>ai</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="99,-216 6,-216 6,-180 99,-180 99,-216"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="99,-216 6,-216 6,-180 99,-180 99,-216"/>
<text text-anchor="middle" x="52.5" y="-200.6" font-family="Helvetica,sans-Serif" font-size="8.00">GoalSelector.tick()</text>
<text text-anchor="middle" x="52.5" y="-191.6" font-family="Helvetica,sans-Serif" font-size="8.00">Brain.tick()</text>
</g>
<!-- ents&#45;&gt;ai -->
<g id="edge9" class="edge">
<title>ents&#45;&gt;ai</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M72.97,-271.62C55.68,-249.22 51.78,-240.52 51.73,-220.42"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="53.14,-220.26 51.77,-216.24 50.34,-220.23 53.14,-220.26"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M72.97,-271.66C55.67,-249.3 51.78,-240.61 51.73,-220.47"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="53.13,-220.3 51.77,-216.28 50.33,-220.27 53.13,-220.3"/>
</g>
<!-- piston -->
<g id="node9" class="node">
<title>piston</title>
<polygon fill="#f8f8f8" stroke="#cccccc" stroke-width="0.4" points="244.5,-216 128.5,-216 128.5,-180 244.5,-180 244.5,-216"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="244.5,-216 128.5,-216 128.5,-180 244.5,-180 244.5,-216"/>
<text text-anchor="middle" x="186.5" y="-200.6" font-family="Helvetica,sans-Serif" font-size="8.00">PistonStructureResolver</text>
<text text-anchor="middle" x="186.5" y="-191.6" font-family="Helvetica,sans-Serif" font-size="8.00">.resolve()</text>
</g>
<!-- blocks&#45;&gt;piston -->
<g id="edge7" class="edge">
<title>blocks&#45;&gt;piston</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M211.96,-271.93C192.75,-249.14 188.22,-240.45 187.01,-220.39"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="188.4,-220.15 186.8,-216.22 185.6,-220.28 188.4,-220.15"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M211.61,-271.6C192.67,-249.16 188.19,-240.47 187,-220.39"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="188.39,-220.15 186.8,-216.22 185.59,-220.28 188.39,-220.15"/>
</g>
<!-- expredst -->
<g id="node14" class="node">
<title>expredst</title>
<polygon fill="#fff8e8" stroke="#ddcc66" stroke-width="0.8" points="443,-220 274,-220 274,-176 443,-176 443,-220"/>
<text text-anchor="middle" x="358.5" y="-209.6" font-family="Helvetica,sans-Serif" font-size="8.00"> minecraft&#45;0003</text>
<polygon fill="white" stroke="black" stroke-width="1.2" stroke-dasharray="5,2" points="443,-220 274,-220 274,-176 443,-176 443,-220"/>
<text text-anchor="middle" x="358.5" y="-209.6" font-family="Helvetica,sans-Serif" font-size="8.00">[!] minecraft&#45;0003</text>
<text text-anchor="middle" x="358.5" y="-200.6" font-family="Helvetica,sans-Serif" font-size="8.00">ExperimentalRedstoneWireEvaluator</text>
<text text-anchor="middle" x="358.5" y="-191.6" font-family="Helvetica,sans-Serif" font-size="8.00">Deque.contains() O(N) in BFS</text>
<text text-anchor="middle" x="358.5" y="-182.6" font-family="Helvetica,sans-Serif" font-size="8.00">MEDIUM — flag&#45;gated</text>
@ -136,36 +136,36 @@
<!-- redst&#45;&gt;expredst -->
<g id="edge12" class="edge">
<title>redst&#45;&gt;expredst</title>
<path fill="none" stroke="#ddcc66" stroke-width="0.8" d="M348.31,-271.75C341.38,-250.34 340.69,-241.31 347.12,-224.17"/>
<polygon fill="#ddcc66" stroke="#ddcc66" stroke-width="0.8" points="348.55,-224.37 348.71,-220.14 345.94,-223.35 348.55,-224.37"/>
<text text-anchor="middle" x="391" y="-244.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#aaaaaa">experimental flag</text>
<path fill="none" stroke="black" stroke-width="0.8" stroke-dasharray="5,2" d="M348.3,-271.91C341.33,-250.59 340.66,-241.6 347.21,-224.15"/>
<polygon fill="black" stroke="black" stroke-width="0.8" points="348.66,-224.27 348.82,-220.04 346.06,-223.25 348.66,-224.27"/>
<text text-anchor="middle" x="391" y="-244.4" font-family="Helvetica,sans-Serif" font-size="7.00">experimental flag</text>
</g>
<!-- defredst -->
<g id="node15" class="node">
<title>defredst</title>
<polygon fill="#f5fff5" stroke="#88cc88" stroke-width="0.4" points="617,-216 472,-216 472,-180 617,-180 617,-216"/>
<polygon fill="white" stroke="black" stroke-width="0.5" points="617,-216 472,-216 472,-180 617,-180 617,-216"/>
<text text-anchor="middle" x="544.5" y="-200.6" font-family="Helvetica,sans-Serif" font-size="8.00">DefaultRedstoneWireEvaluator</text>
<text text-anchor="middle" x="544.5" y="-191.6" font-family="Helvetica,sans-Serif" font-size="8.00">CLEAN — separate Set+Deque</text>
</g>
<!-- redst&#45;&gt;defredst -->
<g id="edge13" class="edge">
<title>redst&#45;&gt;defredst</title>
<path fill="none" stroke="#88cc88" stroke-width="0.5" d="M373.31,-271.97C401.97,-245.26 417.86,-236.55 479.74,-217.38"/>
<polygon fill="#88cc88" stroke="#88cc88" stroke-width="0.5" points="480.47,-218.62 483.88,-216.11 479.65,-215.95 480.47,-218.62"/>
<text text-anchor="middle" x="567" y="-244.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#aaaaaa">default path</text>
<path fill="none" stroke="black" stroke-width="0.5" d="M374.2,-272C402.66,-246.78 418.97,-238.29 483.22,-217.42"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="483.75,-218.72 487.12,-216.16 482.88,-216.06 483.75,-218.72"/>
<text text-anchor="middle" x="567" y="-244.4" font-family="Helvetica,sans-Serif" font-size="7.00">default path</text>
</g>
<!-- reload -->
<g id="node7" class="node">
<title>reload</title>
<polygon fill="#fff0f0" stroke="#ddaaaa" stroke-width="0.4" stroke-dasharray="5,2" points="655.5,-485 551.5,-485 551.5,-449 655.5,-449 655.5,-485"/>
<polygon fill="white" stroke="black" stroke-width="0.8" stroke-dasharray="5,2" points="655.5,-485 551.5,-485 551.5,-449 655.5,-449 655.5,-485"/>
<text text-anchor="middle" x="603.5" y="-469.6" font-family="Helvetica,sans-Serif" font-size="8.00">TagLoader</text>
<text text-anchor="middle" x="603.5" y="-460.6" font-family="Helvetica,sans-Serif" font-size="8.00">(world load / /reload)</text>
</g>
<!-- ds -->
<g id="node8" class="node">
<title>ds</title>
<polygon fill="#fce8e8" stroke="#e88888" points="674,-397 533,-397 533,-353 674,-353 674,-397"/>
<text text-anchor="middle" x="603.5" y="-386.6" font-family="Helvetica,sans-Serif" font-size="8.00"> minecraft&#45;0001</text>
<polygon fill="white" stroke="black" stroke-width="2" stroke-dasharray="5,2" points="674,-397 533,-397 533,-353 674,-353 674,-397"/>
<text text-anchor="middle" x="603.5" y="-386.6" font-family="Helvetica,sans-Serif" font-size="8.00">[!] minecraft&#45;0001</text>
<text text-anchor="middle" x="603.5" y="-377.6" font-family="Helvetica,sans-Serif" font-size="8.00">DependencySorter.isCyclic</text>
<text text-anchor="middle" x="603.5" y="-368.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(E^D) — no visited set</text>
<text text-anchor="middle" x="603.5" y="-359.6" font-family="Helvetica,sans-Serif" font-size="8.00">Exponential on diamond deps</text>
@ -173,75 +173,69 @@
<!-- reload&#45;&gt;ds -->
<g id="edge6" class="edge">
<title>reload&#45;&gt;ds</title>
<path fill="none" stroke="#e88888" d="M606.16,-448.79C607.38,-437.48 607.1,-427.4 605.33,-401.14"/>
<polygon fill="#e88888" stroke="#e88888" points="606.73,-401.04 605.06,-397.15 603.94,-401.23 606.73,-401.04"/>
<text text-anchor="middle" x="632" y="-421.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#aaaaaa">called per edge</text>
<path fill="none" stroke="black" stroke-width="1.5" d="M599.85,-448.93C598.06,-437.3 598.41,-427.37 600.91,-401.14"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="602.3,-401.27 601.29,-397.15 599.52,-401 602.3,-401.27"/>
<text text-anchor="middle" x="632" y="-421.4" font-family="Helvetica,sans-Serif" font-size="7.00">called per edge</text>
</g>
<!-- ps -->
<g id="node10" class="node">
<title>ps</title>
<polygon fill="none" stroke="#cccccc" stroke-width="0.4" stroke-dasharray="5,2" points="233.5,-124 139.5,-124 139.5,-88 233.5,-88 233.5,-124"/>
<polygon fill="white" stroke="black" stroke-width="0.5" stroke-dasharray="5,2" points="248.5,-124 124.5,-124 124.5,-88 248.5,-88 248.5,-124"/>
<text text-anchor="middle" x="186.5" y="-113.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0002</text>
<text text-anchor="middle" x="186.5" y="-104.1" font-family="Helvetica,sans-Serif" font-size="8.00">toPush.contains()</text>
<text text-anchor="middle" x="186.5" y="-95.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(P²) bounded≤12</text>
<text text-anchor="middle" x="186.5" y="-95.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Pu00b2) bounded&lt;=12</text>
</g>
<!-- piston&#45;&gt;ps -->
<g id="edge8" class="edge">
<title>piston&#45;&gt;ps</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M180.23,-179.69C172.01,-154.88 171.03,-145.79 177.28,-128.37"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="178.73,-128.5 178.82,-124.27 176.11,-127.52 178.73,-128.5"/>
<text text-anchor="middle" x="212.5" y="-148.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#aaaaaa">per activation</text>
<path fill="none" stroke="black" stroke-width="0.5" d="M179.99,-179.61C171.63,-155.11 170.81,-146.21 177.53,-127.83"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="178.87,-128.26 178.98,-124.02 176.25,-127.26 178.87,-128.26"/>
<text text-anchor="middle" x="212.5" y="-148.4" font-family="Helvetica,sans-Serif" font-size="7.00">per activation</text>
</g>
<!-- path -->
<g id="node12" class="node">
<title>path</title>
<polygon fill="#f5f5fc" stroke="#aaaadd" stroke-width="0.4" points="93,-124 12,-124 12,-88 93,-88 93,-124"/>
<polygon fill="white" stroke="black" stroke-width="0.8" points="93,-124 12,-124 12,-88 93,-88 93,-124"/>
<text text-anchor="middle" x="52.5" y="-108.6" font-family="Helvetica,sans-Serif" font-size="8.00">PathNavigation</text>
<text text-anchor="middle" x="52.5" y="-99.6" font-family="Helvetica,sans-Serif" font-size="8.00">PathFinder</text>
</g>
<!-- ai&#45;&gt;path -->
<g id="edge10" class="edge">
<title>ai&#45;&gt;path</title>
<path fill="none" stroke="#cccccc" stroke-width="0.5" d="M45.97,-179.7C37.58,-155.32 36.76,-146.43 43.5,-127.96"/>
<polygon fill="#cccccc" stroke="#cccccc" stroke-width="0.5" points="44.85,-128.36 44.95,-124.13 42.23,-127.37 44.85,-128.36"/>
<path fill="none" stroke="black" stroke-width="0.5" d="M45.93,-179.92C37.44,-155.71 36.65,-146.87 43.55,-127.99"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="44.92,-128.3 45.03,-124.07 42.3,-127.31 44.92,-128.3"/>
</g>
<!-- path_q -->
<g id="node13" class="node">
<title>path_q</title>
<polygon fill="none" stroke="#ddcc66" stroke-width="0.4" stroke-dasharray="5,2" points="105,-36 0,-36 0,0 105,0 105,-36"/>
<polygon fill="white" stroke="black" stroke-width="0.5" stroke-dasharray="5,2" points="105,-36 0,-36 0,0 105,0 105,-36"/>
<text text-anchor="middle" x="52.5" y="-20.6" font-family="Helvetica,sans-Serif" font-size="8.00">? scan pending</text>
<text text-anchor="middle" x="52.5" y="-11.6" font-family="Helvetica,sans-Serif" font-size="8.00">A* open set structure</text>
</g>
<!-- path&#45;&gt;path_q -->
<g id="edge11" class="edge">
<title>path&#45;&gt;path_q</title>
<path fill="none" stroke="#ddcc66" stroke-width="0.5" stroke-dasharray="5,2" d="M46.69,-87.95C39.31,-64.3 38.21,-55.32 43.4,-40.16"/>
<polygon fill="#ddcc66" stroke="#ddcc66" stroke-width="0.5" points="44.8,-40.4 44.85,-36.17 42.17,-39.45 44.8,-40.4"/>
<text text-anchor="middle" x="88.5" y="-60.4" font-family="Helvetica,sans-Serif" font-size="7.00" fill="#aaaaaa">under investigation</text>
<path fill="none" stroke="black" stroke-width="0.5" stroke-dasharray="5,2" d="M46.43,-87.84C38.98,-64.79 37.94,-55.92 43.32,-40.37"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="44.77,-40.5 44.83,-36.26 42.14,-39.53 44.77,-40.5"/>
<text text-anchor="middle" x="88.5" y="-60.4" font-family="Helvetica,sans-Serif" font-size="7.00">under investigation</text>
</g>
<!-- l1 -->
<g id="node17" class="node">
<title>l1</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="1108.5,-485 1010.5,-485 1010.5,-449 1108.5,-449 1108.5,-485"/>
<text text-anchor="middle" x="1059.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#e88888"> confirmed defect</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="1310.5,-485 1150.5,-485 1150.5,-449 1310.5,-449 1310.5,-485"/>
<text text-anchor="middle" x="1230.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00">[!] thick border = confirmed defect</text>
</g>
<!-- l2 -->
<g id="node18" class="node">
<title>l2</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="981.5,-485 899.5,-485 899.5,-449 981.5,-449 981.5,-485"/>
<text text-anchor="middle" x="940.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#aaaaaa">bounded / LOW</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="1121.5,-485 949.5,-485 949.5,-449 1121.5,-449 1121.5,-485"/>
<text text-anchor="middle" x="1035.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00">thin border = bounded / LOW / CLEAN</text>
</g>
<!-- l3 -->
<g id="node19" class="node">
<title>l3</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="870,-485 799,-485 799,-449 870,-449 870,-485"/>
<text text-anchor="middle" x="834.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#ddcc66">? under scan</text>
</g>
<!-- l4 -->
<g id="node20" class="node">
<title>l4</title>
<polygon fill="lightgrey" stroke="transparent" stroke-width="0.4" points="770,-485 685,-485 685,-449 770,-449 770,-485"/>
<text text-anchor="middle" x="727.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#aaaadd">not yet scanned</text>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="920.5,-485 684.5,-485 684.5,-449 920.5,-449 920.5,-485"/>
<text text-anchor="middle" x="802.5" y="-465.1" font-family="Helvetica,sans-Serif" font-size="8.00">dashed box = deferred / flag&#45;gated / not&#45;on&#45;tick&#45;path</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -1,83 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 270" width="760" height="270">
<rect width="760" height="270" fill="white"/>
<!-- Title -->
<text x="380" y="15" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="10.5" fill="#333">Minecraft Server-26.1 — DependencySorter.isCyclic · /reload timing · depth-16 modpack datapack</text>
<!-- ── Bar chart ─────────────────────────────────────────────────────────── -->
<!-- Chart area: x=130665 (535px), y=30120 -->
<!-- Scale: 535 / 20000 = 0.02675 px/ms -->
<!-- Vanilla: 19255 * 0.02675 = 515px Patched: 3087 * 0.02675 = 83px -->
<!-- Y labels -->
<text x="125" y="58" text-anchor="end" font-family="Helvetica,sans-serif" font-size="9" fill="#555">Vanilla</text>
<text x="125" y="98" text-anchor="end" font-family="Helvetica,sans-serif" font-size="9" fill="#555">Patched</text>
<!-- Vanilla bar (red) -->
<rect x="130" y="38" width="515" height="30" rx="2" fill="#fcc" stroke="#e05555" stroke-width="0.8"/>
<text x="651" y="58" font-family="Helvetica,sans-serif" font-size="9" fill="#cc3333">19,255 ms</text>
<!-- Patched bar (green) -->
<rect x="130" y="78" width="83" height="30" rx="2" fill="#c8eec8" stroke="#558855" stroke-width="0.8"/>
<text x="219" y="98" font-family="Helvetica,sans-serif" font-size="9" fill="#336633">3,087 ms</text>
<!-- X axis -->
<line x1="130" y1="120" x2="665" y2="120" stroke="#aaa" stroke-width="0.5"/>
<!-- Ticks and labels -->
<line x1="130" y1="120" x2="130" y2="125" stroke="#888" stroke-width="0.5"/>
<line x1="264" y1="120" x2="264" y2="125" stroke="#888" stroke-width="0.5"/>
<line x1="397" y1="120" x2="397" y2="125" stroke="#888" stroke-width="0.5"/>
<line x1="531" y1="120" x2="531" y2="125" stroke="#888" stroke-width="0.5"/>
<line x1="665" y1="120" x2="665" y2="125" stroke="#888" stroke-width="0.5"/>
<text x="130" y="134" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#777">0</text>
<text x="264" y="134" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#777">5,000 ms</text>
<text x="397" y="134" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#777">10,000 ms</text>
<text x="531" y="134" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#777">15,000 ms</text>
<text x="665" y="134" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="7.5" fill="#777">20,000 ms</text>
<!-- Speedup callout -->
<rect x="290" y="144" width="180" height="28" rx="4" fill="#f0fff0" stroke="#66aa66" stroke-width="1.0"/>
<text x="380" y="162" text-anchor="middle" font-family="Helvetica,sans-serif" font-size="14" fill="#336633" font-weight="bold">6.2× faster after patch</text>
<!-- ── Depth scaling table ─────────────────────────────────────────────── -->
<text x="20" y="196" font-family="Helvetica,sans-serif" font-size="9" fill="#555" font-weight="bold">Depth scaling (real server reload):</text>
<!-- Table header -->
<text x="20" y="210" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Depth</text>
<text x="80" y="210" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Vanilla /reload</text>
<text x="200" y="210" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Patched /reload</text>
<text x="320" y="210" font-family="Helvetica,sans-serif" font-size="8" fill="#888">Speedup</text>
<text x="390" y="210" font-family="Helvetica,sans-serif" font-size="8" fill="#888">isCyclic calls (theory)</text>
<line x1="14" y1="213" x2="600" y2="213" stroke="#ddd" stroke-width="0.5"/>
<!-- Row: D=16 (real) -->
<text x="20" y="225" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">D = 16</text>
<text x="80" y="225" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc3333">19,255 ms</text>
<text x="200" y="225" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633">3,087 ms</text>
<text x="320" y="225" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633" font-weight="bold">6.2×</text>
<text x="390" y="225" font-family="Helvetica,sans-serif" font-size="8.5" fill="#555">~53 M vanilla vs ~1,600 patched (33,000×)</text>
<text x="560" y="225" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">← real benchmark</text>
<!-- Row: D=14 (microbench) -->
<text x="20" y="240" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">D = 14</text>
<text x="80" y="240" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc3333">~7,432 µs/call</text>
<text x="200" y="240" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633">~67 µs/call</text>
<text x="320" y="240" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633" font-weight="bold">110.9×</text>
<text x="390" y="240" font-family="Helvetica,sans-serif" font-size="8.5" fill="#555">~13 M nodes per call vs O(1) with visited set</text>
<text x="560" y="240" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">← microbenchmark</text>
<!-- Row: D=16 overflow note -->
<text x="20" y="255" font-family="Helvetica,sans-serif" font-size="8.5" fill="#333">D ≥ 16</text>
<text x="80" y="255" font-family="Helvetica,sans-serif" font-size="8.5" fill="#cc3333">StackOverflowError</text>
<text x="200" y="255" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633">stable (iterative)</text>
<text x="320" y="255" font-family="Helvetica,sans-serif" font-size="8.5" fill="#336633" font-weight="bold">∞ effective</text>
<text x="390" y="255" font-family="Helvetica,sans-serif" font-size="8.5" fill="#555">vanilla crashes; patch never overflows</text>
<text x="560" y="255" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">← before-patch behavior</text>
<!-- Fork coverage note -->
<text x="620" y="196" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">All forks confirmed affected:</text>
<text x="620" y="207" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">Paper · Spigot · Purpur</text>
<text x="620" y="218" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">Forge · NeoForge · Fabric</text>
<text x="620" y="229" font-family="Helvetica,sans-serif" font-size="7.5" fill="#888">Quilt · Arclight (stretch)</text>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: mc_server_speedup Pages: 1 -->
<svg width="480pt" height="1076pt"
viewBox="0.00 0.00 480.00 1075.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 1039.5)">
<title>mc_server_speedup</title>
<polygon fill="white" stroke="transparent" points="-36,36 -36,-1039.5 444,-1039.5 444,36 -36,36"/>
<text text-anchor="middle" x="204" y="-990.7" font-family="Helvetica,sans-Serif" font-size="11.00">Minecraft Server&#45;26.1 — CWE&#45;407 Speedups (real benchmarks, JDK 25)</text>
<g id="clust7" class="cluster">
<title>cluster_legend</title>
<polygon fill="white" stroke="black" stroke-width="0.5" stroke-dasharray="1,5" points="96,-834.5 96,-975.5 312,-975.5 312,-834.5 96,-834.5"/>
<text text-anchor="middle" x="170" y="-965.1" font-family="Helvetica,sans-Serif" font-size="8.00">Key: border thickness = severity</text>
</g>
<!-- b1 -->
<g id="node1" class="node">
<title>b1</title>
<polygon fill="white" stroke="black" stroke-width="2" points="276.5,-194.5 131.5,-194.5 131.5,-128.5 276.5,-128.5 276.5,-194.5"/>
<text text-anchor="middle" x="204" y="-182.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0001</text>
<text text-anchor="middle" x="204" y="-173.1" font-family="Helvetica,sans-Serif" font-size="8.00">DependencySorter.isCyclic</text>
<text text-anchor="middle" x="204" y="-164.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(E^D) EXPONENTIAL</text>
<text text-anchor="middle" x="204" y="-155.1" font-family="Helvetica,sans-Serif" font-size="8.00">Depth 14: 7,432 us/op</text>
<text text-anchor="middle" x="204" y="-146.1" font-family="Helvetica,sans-Serif" font-size="8.00">Depth 16+: STACK OVERFLOW</text>
<text text-anchor="middle" x="204" y="-137.1" font-family="Helvetica,sans-Serif" font-size="8.00">Trigger: world load, /reload</text>
</g>
<!-- a1 -->
<g id="node5" class="node">
<title>a1</title>
<polygon fill="white" stroke="black" stroke-width="0.8" points="274,-57 134,-57 134,0 274,0 274,-57"/>
<text text-anchor="middle" x="204" y="-44.6" font-family="Helvetica,sans-Serif" font-size="8.00">visited HashSet per call</text>
<text text-anchor="middle" x="204" y="-35.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(E) per call</text>
<text text-anchor="middle" x="204" y="-26.6" font-family="Helvetica,sans-Serif" font-size="8.00">Depth 14: 67 us/op</text>
<text text-anchor="middle" x="204" y="-17.6" font-family="Helvetica,sans-Serif" font-size="8.00">110.9x faster</text>
<text text-anchor="middle" x="204" y="-8.6" font-family="Helvetica,sans-Serif" font-size="8.00">Depth 16+: runs fine (linear)</text>
</g>
<!-- b1&#45;&gt;a1 -->
<g id="edge1" class="edge">
<title>b1&#45;&gt;a1</title>
<path fill="none" stroke="black" stroke-width="2.5" d="M204,-28.97C204,-67.63 204,-68.73 204,-156.17"/>
<polygon fill="black" stroke="black" stroke-width="2.5" points="202.25,-156.23 204,-161.23 205.75,-156.23 202.25,-156.23"/>
</g>
<!-- b2 -->
<g id="node2" class="node">
<title>b2</title>
<polygon fill="white" stroke="black" stroke-width="0.6" points="277,-389.5 131,-389.5 131,-341.5 277,-341.5 277,-389.5"/>
<text text-anchor="middle" x="204" y="-377.1" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0002</text>
<text text-anchor="middle" x="204" y="-368.1" font-family="Helvetica,sans-Serif" font-size="8.00">PistonStructureResolver</text>
<text text-anchor="middle" x="204" y="-359.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(Pu00b2) — bounded P&lt;=12</text>
<text text-anchor="middle" x="204" y="-350.1" font-family="Helvetica,sans-Serif" font-size="8.00">Piston activation</text>
</g>
<!-- a2 -->
<g id="node6" class="node">
<title>a2</title>
<polygon fill="white" stroke="black" stroke-width="0.8" points="274,-270 134,-270 134,-231 274,-231 274,-270"/>
<text text-anchor="middle" x="204" y="-257.6" font-family="Helvetica,sans-Serif" font-size="8.00">parallel HashSet&lt;BlockPos&gt;</text>
<text text-anchor="middle" x="204" y="-248.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) contains</text>
<text text-anchor="middle" x="204" y="-239.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.1x (max 144 checks)</text>
</g>
<!-- b2&#45;&gt;a2 -->
<g id="edge2" class="edge">
<title>b2&#45;&gt;a2</title>
<path fill="none" stroke="black" stroke-width="0.5" d="M204,-250.9C204,-284.2 204,-285.28 204,-360"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="202.25,-360.03 204,-365.03 205.75,-360.03 202.25,-360.03"/>
</g>
<!-- b3 -->
<g id="node3" class="node">
<title>b3</title>
<polygon fill="white" stroke="black" stroke-width="1.2" points="292.5,-602 115.5,-602 115.5,-545 292.5,-545 292.5,-602"/>
<text text-anchor="middle" x="204" y="-589.6" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0003</text>
<text text-anchor="middle" x="204" y="-580.6" font-family="Helvetica,sans-Serif" font-size="8.00">ExperimentalRedstoneWireEvaluator</text>
<text text-anchor="middle" x="204" y="-571.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(Nu00b2) — Deque.contains() in BFS</text>
<text text-anchor="middle" x="204" y="-562.6" font-family="Helvetica,sans-Serif" font-size="8.00">Redstone update (flag&#45;gated)</text>
<text text-anchor="middle" x="204" y="-553.6" font-family="Helvetica,sans-Serif" font-size="8.00">N=500 wires: ~O(250K) checks</text>
</g>
<!-- a3 -->
<g id="node7" class="node">
<title>a3</title>
<polygon fill="white" stroke="black" stroke-width="0.8" points="281.5,-473.5 126.5,-473.5 126.5,-425.5 281.5,-425.5 281.5,-473.5"/>
<text text-anchor="middle" x="204" y="-461.1" font-family="Helvetica,sans-Serif" font-size="8.00">companion HashSet&lt;BlockPos&gt;</text>
<text text-anchor="middle" x="204" y="-452.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) per enqueue check</text>
<text text-anchor="middle" x="204" y="-443.1" font-family="Helvetica,sans-Serif" font-size="8.00">O(N) total BFS</text>
<text text-anchor="middle" x="204" y="-434.1" font-family="Helvetica,sans-Serif" font-size="8.00">~Nx speedup at scale</text>
</g>
<!-- b3&#45;&gt;a3 -->
<g id="edge3" class="edge">
<title>b3&#45;&gt;a3</title>
<path fill="none" stroke="black" stroke-width="1.2" d="M204,-449.75C204,-531.58 204,-536.08 204,-567.74"/>
<polygon fill="black" stroke="black" stroke-width="1.2" points="202.25,-568.07 204,-573.07 205.75,-568.07 202.25,-568.07"/>
</g>
<!-- b4 -->
<g id="node4" class="node">
<title>b4</title>
<polygon fill="white" stroke="black" stroke-width="0.6" points="281.5,-806 126.5,-806 126.5,-749 281.5,-749 281.5,-806"/>
<text text-anchor="middle" x="204" y="-793.6" font-family="Helvetica,sans-Serif" font-size="8.00">minecraft&#45;0004</text>
<text text-anchor="middle" x="204" y="-784.6" font-family="Helvetica,sans-Serif" font-size="8.00">MoveThroughVillageGoal</text>
<text text-anchor="middle" x="204" y="-775.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(Nu00b2) — linear scan in loop</text>
<text text-anchor="middle" x="204" y="-766.6" font-family="Helvetica,sans-Serif" font-size="8.00">Bounded N&lt;=15</text>
<text text-anchor="middle" x="204" y="-757.6" font-family="Helvetica,sans-Serif" font-size="8.00">Villager pathfinding</text>
</g>
<!-- a4 -->
<g id="node8" class="node">
<title>a4</title>
<polygon fill="white" stroke="black" stroke-width="0.8" points="281.5,-677 126.5,-677 126.5,-638 281.5,-638 281.5,-677"/>
<text text-anchor="middle" x="204" y="-664.6" font-family="Helvetica,sans-Serif" font-size="8.00">companion HashSet&lt;BlockPos&gt;</text>
<text text-anchor="middle" x="204" y="-655.6" font-family="Helvetica,sans-Serif" font-size="8.00">O(1) hasNotVisited</text>
<text text-anchor="middle" x="204" y="-646.6" font-family="Helvetica,sans-Serif" font-size="8.00">~1.0x (max 15 entries)</text>
</g>
<!-- b4&#45;&gt;a4 -->
<g id="edge4" class="edge">
<title>b4&#45;&gt;a4</title>
<path fill="none" stroke="black" stroke-width="0.5" d="M204,-657.99C204,-736.95 204,-741.31 204,-771.93"/>
<polygon fill="black" stroke="black" stroke-width="0.5" points="202.25,-772.08 204,-777.08 205.75,-772.08 202.25,-772.08"/>
</g>
<!-- lexp -->
<g id="node9" class="node">
<title>lexp</title>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="286.5,-950.5 121.5,-950.5 121.5,-914.5 286.5,-914.5 286.5,-950.5"/>
<text text-anchor="middle" x="204" y="-930.6" font-family="Helvetica,sans-Serif" font-size="8.00">thick dashed = EXPONENTIAL/HIGH</text>
</g>
<!-- llow -->
<g id="node10" class="node">
<title>llow</title>
<polygon fill="white" stroke="transparent" stroke-width="0.8" points="304,-878.5 104,-878.5 104,-842.5 304,-842.5 304,-878.5"/>
<text text-anchor="middle" x="204" y="-858.6" font-family="Helvetica,sans-Serif" font-size="8.00">thin = LOW/bounded (fixed for correctness)</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before After
Before After

View file

@ -22,7 +22,7 @@ h1 {
font-weight: 700;
color: #0f0f0f;
margin: 0 0 0.2em 0;
border-bottom: 3px solid #c00;
border-bottom: 3px solid #000;
padding-bottom: 0.3em;
line-height: 1.2;
}
@ -32,7 +32,7 @@ h2 {
font-weight: 700;
color: #0f0f0f;
margin: 1.8em 0 0.5em 0;
border-bottom: 1px solid #ddd;
border-bottom: 1px solid #000;
padding-bottom: 0.2em;
}
@ -50,25 +50,25 @@ p {
code {
font-family: 'Consolas', 'Liberation Mono', 'DejaVu Sans Mono', monospace;
font-size: 9.5pt;
background: #f4f4f4;
border: 1px solid #e0e0e0;
border-radius: 3px;
background: none;
border: 1px solid #aaa;
border-radius: 2px;
padding: 0.1em 0.3em;
color: #b00;
color: #000;
}
pre {
font-family: 'Consolas', 'Liberation Mono', 'DejaVu Sans Mono', monospace;
font-size: 9pt;
background: #f8f8f8;
border: 1px solid #ddd;
border-left: 4px solid #c00;
border-radius: 3px;
background: none;
border: 1px solid #999;
border-left: 4px solid #000;
border-radius: 2px;
padding: 0.8em 1em;
overflow-x: auto;
margin: 0.8em 0;
line-height: 1.45;
color: #1a1a1a;
color: #000;
}
pre code {
@ -87,26 +87,28 @@ table {
}
th {
background: #1a1a1a;
color: #fff;
background: none;
color: #000;
padding: 0.4em 0.7em;
text-align: left;
font-weight: 600;
font-weight: 700;
font-size: 9.5pt;
border-bottom: 2px solid #000;
border-top: 1px solid #000;
}
td {
padding: 0.35em 0.7em;
border-bottom: 1px solid #e8e8e8;
border-bottom: 1px solid #ccc;
vertical-align: top;
}
tr:nth-child(even) td {
background: #fafafa;
background: none;
}
tr:hover td {
background: #f0f4ff;
background: none;
}
strong {
@ -129,28 +131,29 @@ li {
hr {
border: none;
border-top: 2px solid #e0e0e0;
border-top: 1px solid #000;
margin: 2em 0;
}
blockquote {
border-left: 4px solid #c00;
border-left: 4px solid #000;
margin: 0.8em 0;
padding: 0.5em 1em;
background: #fff8f8;
color: #333;
background: none;
color: #000;
}
/* Draft watermark band */
.draft-banner {
background: #c00;
color: #fff;
background: none;
color: #000;
text-align: center;
font-size: 9pt;
font-weight: 700;
letter-spacing: 0.15em;
padding: 0.3em;
margin-bottom: 1.5em;
border: 1px solid #000;
}
/* Page breaks */
@ -164,10 +167,10 @@ pre { page-break-inside: avoid; }
a { color: inherit; text-decoration: none; }
}
/* Cover page */
/* Cover page — print-friendly: white background, black border box, no ink flood */
.cover {
background: #000;
color: #fff;
background: #fff;
color: #000;
min-height: 100vh;
display: flex;
flex-direction: column;
@ -177,22 +180,30 @@ pre { page-break-inside: avoid; }
margin: -2.5cm -2cm 2cm -2cm;
padding: 4cm 2cm;
page-break-after: always;
border: 4px solid #000;
}
.cover-title {
font-family: 'ChunkFive', 'Rockwell', 'Courier New', serif;
font-size: 64pt;
font-weight: normal;
color: #fff;
color: #000;
letter-spacing: -0.01em;
line-height: 1;
margin: 0 0 0.4em 0;
margin: 0 0 0.15em 0;
}
.cover-title-rule {
width: 8cm;
border: none;
border-top: 3px solid #000;
margin: 0.3em auto 0.5em auto;
}
.cover-subtitle {
font-family: 'Helvetica Neue', Arial, sans-serif;
font-size: 13pt;
color: #aaa;
color: #000;
font-weight: 400;
letter-spacing: 0.05em;
text-transform: uppercase;
@ -202,14 +213,14 @@ pre { page-break-inside: avoid; }
.cover-date {
font-family: 'Helvetica Neue', Arial, sans-serif;
font-size: 10pt;
color: #666;
color: #333;
margin-top: 1em;
}
.cover-authors {
font-family: 'Helvetica Neue', Arial, sans-serif;
font-size: 9.5pt;
color: #555;
color: #333;
margin-top: 0.5em;
letter-spacing: 0.01em;
}