moxml 0.5.149 → 0.5.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/dependent-repos.json +7 -2
- data/.github/workflows/dependent-tests.yml +4 -1
- data/.github/workflows/performance-release.yml +79 -0
- data/.github/workflows/performance.yml +59 -0
- data/Rakefile +23 -0
- data/benchmark/README.md +106 -0
- data/benchmark/scoreboard.json +115 -0
- data/benchmark/scoreboard.rb +556 -0
- data/bin/generate-model-coverage +21 -0
- data/docs/_pages/adapter-compatibility.adoc +3 -3
- data/docs/_pages/divergences.adoc +32 -41
- data/docs/_pages/ecosystem.adoc +62 -0
- data/docs/_pages/headed-ox-limitations.adoc +1 -1
- data/docs/_pages/headed-ox.adoc +2 -2
- data/docs/_pages/index.adoc +4 -0
- data/docs/_pages/model-coverage.adoc +57 -0
- data/docs/_pages/performance.adoc +29 -0
- data/docs/_pages/why-moxml.adoc +87 -0
- data/docs/_references/processing-model.adoc +42 -3
- data/lib/moxml/adapter/base.rb +73 -0
- data/lib/moxml/adapter/leptris.rb +183 -4
- data/lib/moxml/adapter/libxml.rb +34 -2
- data/lib/moxml/adapter/nokogiri.rb +10 -0
- data/lib/moxml/adapter/oga.rb +39 -7
- data/lib/moxml/adapter/ox.rb +8 -0
- data/lib/moxml/adapter/rexml.rb +17 -2
- data/lib/moxml/c14n/data_model.rb +8 -0
- data/lib/moxml/c14n/processor.rb +17 -8
- data/lib/moxml/context.rb +28 -0
- data/lib/moxml/document.rb +17 -3
- data/lib/moxml/node.rb +56 -5
- data/lib/moxml/node_set.rb +31 -1
- data/lib/moxml/relaxng.rb +62 -0
- data/lib/moxml/sax/block_handler.rb +7 -0
- data/lib/moxml/sax/handler.rb +20 -0
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xpath.rb +28 -0
- data/lib/moxml.rb +1 -0
- data/spec/consistency/adapter_parity_spec.rb +22 -0
- data/spec/consistency/citation_hygiene_spec.rb +30 -0
- data/spec/consistency/model_coverage_audit_spec.rb +61 -86
- data/spec/consistency/published_docs_spec.rb +49 -0
- data/spec/consistency/xpath_idioms_spec.rb +23 -5
- data/spec/integration/shared_examples/edge_cases.rb +0 -13
- data/spec/moxml/adapter/leptris_spec.rb +23 -3
- data/spec/moxml/adapter/shared_examples/adapter_contract.rb +0 -8
- data/spec/moxml/attribute_resolver_spec.rb +33 -0
- data/spec/moxml/c14n/adapter_delegation_spec.rb +33 -6
- data/spec/moxml/c14n/character_encoding_spec.rb +7 -13
- data/spec/moxml/c14n/comments_pis_spec.rb +35 -8
- data/spec/moxml/c14n/subset_spec.rb +2 -12
- data/spec/moxml/c14n/w3c_examples_spec.rb +2 -5
- data/spec/moxml/element_indent_spec.rb +34 -0
- data/spec/moxml/node_spec.rb +0 -3
- data/spec/moxml/relax_ng_spec.rb +67 -0
- data/spec/moxml/sax_spec.rb +45 -74
- data/spec/moxml/xpath_capabilities_spec.rb +11 -38
- data/spec/support/input_taxonomy.rb +7 -0
- data/spec/support/model_coverage.rb +159 -0
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73b67b633933c60095bdeafd744a8f7a827066edf478245e9c2f49aadf1d75e6
|
|
4
|
+
data.tar.gz: 92320b13e8bb745cd5b650e85d4fa7b8397e082871a7c255cb61f637595c6048
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c34b4df4cf09797b5a28ec909e0df41c970897676154fa1b66dc9ebbd18cdccb13408b83f5647c44d41cfda7ebcbf09571314d0bfe71b572a58dde972e78994b
|
|
7
|
+
data.tar.gz: d926c442a8b0dc0f9d159f27f42772a3af48358fbbd67d62d7cec1cdd51c609110def03466fa93c5b95b2eccfdaa7ab34e26c818b30b2651a996b9879c63d699
|
|
@@ -24,4 +24,7 @@ jobs:
|
|
|
24
24
|
rake:
|
|
25
25
|
uses: metanorma/ci/.github/workflows/dependent-rake.yml@main
|
|
26
26
|
with:
|
|
27
|
-
command: bundle exec rspec
|
|
27
|
+
command: bundle exec rspec
|
|
28
|
+
# metanorma-ietf needs xml2rfc; metanorma-standoc needs
|
|
29
|
+
# ghostscript. Both are harmless for the other consumers.
|
|
30
|
+
setup-tools: xml2rfc,ghostscript
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: performance-release
|
|
2
|
+
|
|
3
|
+
# Every release re-measures the scoreboard and appends the table to
|
|
4
|
+
# the release notes (TODO.sota/04). Triggered by the release
|
|
5
|
+
# workflow's completion; idempotent — a re-run replaces the marked
|
|
6
|
+
# section instead of stacking it.
|
|
7
|
+
on:
|
|
8
|
+
workflow_run:
|
|
9
|
+
workflows: ["release"]
|
|
10
|
+
types: [completed]
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: write
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
report:
|
|
22
|
+
if: >-
|
|
23
|
+
github.event_name == 'workflow_dispatch' ||
|
|
24
|
+
github.event.workflow_run.conclusion == 'success'
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
with:
|
|
29
|
+
ref: main
|
|
30
|
+
submodules: "recursive"
|
|
31
|
+
|
|
32
|
+
- name: Set up Ruby
|
|
33
|
+
uses: ruby/setup-ruby@v1
|
|
34
|
+
with:
|
|
35
|
+
ruby-version: "3.3"
|
|
36
|
+
bundler-cache: false
|
|
37
|
+
|
|
38
|
+
- name: Install ragel
|
|
39
|
+
run: sudo apt-get update && sudo apt-get install -y ragel
|
|
40
|
+
|
|
41
|
+
- name: Install ruby-ll (for rake vendor:prepare)
|
|
42
|
+
run: gem install ruby-ll --no-document
|
|
43
|
+
|
|
44
|
+
- name: Generate ragel / ruby-ll outputs in vendored forks
|
|
45
|
+
run: rake vendor:prepare
|
|
46
|
+
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: bundle install
|
|
49
|
+
|
|
50
|
+
- name: Compile liboga / libll native extensions
|
|
51
|
+
run: rake vendor:compile
|
|
52
|
+
|
|
53
|
+
- name: Measure the scoreboard
|
|
54
|
+
run: |
|
|
55
|
+
SCORE_MARKDOWN=/tmp/section.md \
|
|
56
|
+
bundle exec ruby benchmark/scoreboard.rb
|
|
57
|
+
|
|
58
|
+
- name: Append the scoreboard to the latest release notes
|
|
59
|
+
env:
|
|
60
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
61
|
+
run: |
|
|
62
|
+
TAG=$(gh release view --json tagName --jq .tagName)
|
|
63
|
+
gh release view "$TAG" --json body --jq .body > /tmp/body.md
|
|
64
|
+
ruby -e '
|
|
65
|
+
body = File.read("/tmp/body.md")
|
|
66
|
+
section = File.read("/tmp/section.md")
|
|
67
|
+
block = "<!-- PERFORMANCE:BEGIN -->\n#{section}" \
|
|
68
|
+
"<!-- PERFORMANCE:END -->"
|
|
69
|
+
if body.include?("<!-- PERFORMANCE:BEGIN -->")
|
|
70
|
+
body = body.sub(
|
|
71
|
+
/<!-- PERFORMANCE:BEGIN -->.*<!-- PERFORMANCE:END -->/m,
|
|
72
|
+
block,
|
|
73
|
+
)
|
|
74
|
+
else
|
|
75
|
+
body = body.chomp + "\n\n" + block
|
|
76
|
+
end
|
|
77
|
+
File.write("/tmp/new_body.md", body)
|
|
78
|
+
'
|
|
79
|
+
gh release edit "$TAG" --notes-file /tmp/new_body.md
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: performance
|
|
2
|
+
|
|
3
|
+
# The published scoreboard lock (TODO.sota/04). Runs on a quiet
|
|
4
|
+
# weekly schedule (and on demand); PRs do not run it — measurement
|
|
5
|
+
# noise is a release concern, not a change-gating one.
|
|
6
|
+
on:
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: "0 4 * * 1"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
lock:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
|
+
with:
|
|
24
|
+
submodules: "recursive"
|
|
25
|
+
|
|
26
|
+
- name: Set up Ruby
|
|
27
|
+
uses: ruby/setup-ruby@v1
|
|
28
|
+
with:
|
|
29
|
+
ruby-version: "3.3"
|
|
30
|
+
# bundler-cache is disabled because the path-source oga and
|
|
31
|
+
# ruby-ll forks need generated outputs before their C
|
|
32
|
+
# extensions can compile.
|
|
33
|
+
bundler-cache: false
|
|
34
|
+
|
|
35
|
+
- name: Install ragel
|
|
36
|
+
run: sudo apt-get update && sudo apt-get install -y ragel
|
|
37
|
+
|
|
38
|
+
- name: Install ruby-ll (for rake vendor:prepare)
|
|
39
|
+
run: gem install ruby-ll --no-document
|
|
40
|
+
|
|
41
|
+
- name: Generate ragel / ruby-ll outputs in vendored forks
|
|
42
|
+
run: rake vendor:prepare
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: bundle install
|
|
46
|
+
|
|
47
|
+
- name: Compile liboga / libll native extensions
|
|
48
|
+
run: rake vendor:compile
|
|
49
|
+
|
|
50
|
+
- name: Scoreboard lock (parity rows + 10% regression tolerance)
|
|
51
|
+
run: bundle exec rake benchmark:lock
|
|
52
|
+
|
|
53
|
+
- name: Upload the measured scoreboard
|
|
54
|
+
if: always()
|
|
55
|
+
uses: actions/upload-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
name: scoreboard
|
|
58
|
+
path: benchmark/scoreboard.json
|
|
59
|
+
if-no-files-found: ignore
|
data/Rakefile
CHANGED
|
@@ -284,6 +284,22 @@ namespace :benchmark do
|
|
|
284
284
|
task :report do
|
|
285
285
|
ruby "benchmarks/generate_report.rb"
|
|
286
286
|
end
|
|
287
|
+
|
|
288
|
+
# Published scoreboard (TODO.sota/04): CPU medians, interleaved A/B,
|
|
289
|
+
# load-gated; see benchmark/README.md for the protocol and rows.
|
|
290
|
+
desc "Published performance scoreboard (CPU medians, interleaved A/B)"
|
|
291
|
+
task :scoreboard do
|
|
292
|
+
sh "bundle exec ruby benchmark/scoreboard.rb"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# CI lock: parity rows must be >= 1.0x and no row may fall more than
|
|
296
|
+
# 10% below the committed baseline.
|
|
297
|
+
desc "Scoreboard regression lock (parity + 10% baseline tolerance)"
|
|
298
|
+
task :lock do
|
|
299
|
+
sh({ "SCORE_LOCK" => "1",
|
|
300
|
+
"SCORE_BASELINE" => "benchmark/scoreboard.json" },
|
|
301
|
+
"bundle exec ruby benchmark/scoreboard.rb")
|
|
302
|
+
end
|
|
287
303
|
end
|
|
288
304
|
|
|
289
305
|
namespace :opal do
|
|
@@ -324,4 +340,11 @@ namespace :opal do
|
|
|
324
340
|
end
|
|
325
341
|
end
|
|
326
342
|
|
|
343
|
+
namespace :docs do
|
|
344
|
+
desc "Regenerate the published model-coverage page from the matrix"
|
|
345
|
+
task :coverage do
|
|
346
|
+
sh "bundle exec ruby -I spec bin/generate-model-coverage"
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
327
350
|
task default: :spec
|
data/benchmark/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Performance scoreboard
|
|
2
|
+
|
|
3
|
+
`benchmark/scoreboard.rb` is the published performance surface
|
|
4
|
+
(TODO.sota/04). It answers one question for every operation a
|
|
5
|
+
consumer runs: **how does moxml on its fastest engine lane compare
|
|
6
|
+
with raw nokogiri on the same operation?**
|
|
7
|
+
|
|
8
|
+
## Protocol
|
|
9
|
+
|
|
10
|
+
- **CPU time medians** (`CLOCK_PROCESS_CPUTIME_ID`), not wall time —
|
|
11
|
+
scheduler noise never becomes a performance claim.
|
|
12
|
+
- **Interleaved A/B**: baseline and candidate alternate every
|
|
13
|
+
repetition in the same thermal window; warmups are discarded and
|
|
14
|
+
GC runs between samples. The ratio is `median(baseline) /
|
|
15
|
+
median(candidate)`; `> 1.0x` means moxml is faster.
|
|
16
|
+
- **Load gate**: the harness refuses to report when the 1-minute
|
|
17
|
+
load exceeds half the CPU count. `SCORE_FORCE=1` overrides for
|
|
18
|
+
smoke runs only — such numbers are not publishable.
|
|
19
|
+
- Rows name the exact operation measured; lazy and materialized
|
|
20
|
+
XPath results are separate rows because they cost different things.
|
|
21
|
+
- The pair is **moxml + leptris latest**; the baseline is raw
|
|
22
|
+
nokogiri on the same document.
|
|
23
|
+
|
|
24
|
+
## Rows
|
|
25
|
+
|
|
26
|
+
| Row | Operation | Kind |
|
|
27
|
+
| --- | --------- | ---- |
|
|
28
|
+
| `parse` | `Nokogiri::XML` vs `ctx.parse` on the catalog document | parity |
|
|
29
|
+
| `serialize` | `doc.to_xml` | parity |
|
|
30
|
+
| `xpath //field (count)` | node-set cardinality, nothing materialized | parity |
|
|
31
|
+
| `xpath //field (each)` | iterate every result (wrapper materialization) | structural |
|
|
32
|
+
| `attr pairs listing` | collect `[name, value]` for every record | parity |
|
|
33
|
+
| `build add_element` | create + attach 300 records x 4 fields with attrs and text | structural |
|
|
34
|
+
| `walk+read (warm)` | traverse a pre-parsed document, read name + text | structural |
|
|
35
|
+
| `walk+read (cold)` | parse + the same traversal | structural |
|
|
36
|
+
| `children recursion (cold)` | parse + recurse via `children` filtering elements | structural |
|
|
37
|
+
| `plan records (typed)` | compiled `Moxml::Plan` vs the hand-written typed walk | data API |
|
|
38
|
+
|
|
39
|
+
**Parity rows** are the commitment: the lock fails below a 0.95
|
|
40
|
+
measurement floor. **Structural rows** are measured and trend-locked
|
|
41
|
+
(no row may regress >10% against the committed baseline), but they
|
|
42
|
+
are known to be below parity — the gaps are listed below. **Data
|
|
43
|
+
API** rows are informational: they show what consumers gain by using
|
|
44
|
+
the record APIs instead of node-by-node access.
|
|
45
|
+
|
|
46
|
+
## Commands
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Every row, human-readable
|
|
50
|
+
bundle exec rake benchmark:scoreboard
|
|
51
|
+
|
|
52
|
+
# One or more rows
|
|
53
|
+
SCORE_ROWS="parse,serialize" bundle exec ruby benchmark/scoreboard.rb
|
|
54
|
+
|
|
55
|
+
# Another engine lane
|
|
56
|
+
SCORE_ADAPTER=oga bundle exec ruby benchmark/scoreboard.rb
|
|
57
|
+
|
|
58
|
+
# Machine-readable results (protocol metadata + rows)
|
|
59
|
+
SCORE_JSON=benchmark/scoreboard.json bundle exec ruby benchmark/scoreboard.rb
|
|
60
|
+
|
|
61
|
+
# CI lock: parity rows >= 1.0x, and no row > 10% below the baseline
|
|
62
|
+
SCORE_LOCK=1 SCORE_BASELINE=benchmark/scoreboard.json \
|
|
63
|
+
bundle exec ruby benchmark/scoreboard.rb
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
A smoke run on a loaded machine:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
SCORE_FORCE=1 SCORE_REPS=5 bundle exec ruby benchmark/scoreboard.rb
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Honest status
|
|
73
|
+
|
|
74
|
+
Reference run (generated; do not edit by hand — `SCORE_PUBLISH=1`
|
|
75
|
+
rewrites this block and `docs/_pages/performance.adoc`):
|
|
76
|
+
|
|
77
|
+
<!-- SCOREBOARD:BEGIN -->
|
|
78
|
+
| Row | Ratio | Kind | Status |
|
|
79
|
+
| --- | ----- | ---- | ------ |
|
|
80
|
+
| `parse` | 2.59x | parity | met |
|
|
81
|
+
| `serialize` | 1.35x | parity | met |
|
|
82
|
+
| `xpath //field (count)` | 1.20x | parity | met |
|
|
83
|
+
| `xpath //field (each)` | 0.34x | structural | tracked (below parity) |
|
|
84
|
+
| `attr pairs listing` | 8.16x | parity | met |
|
|
85
|
+
| `build add_element` | 0.60x | structural | tracked (below parity) |
|
|
86
|
+
| `walk+read (warm)` | 0.77x | structural | tracked (below parity) |
|
|
87
|
+
| `walk+read (cold)` | 0.22x | structural | tracked (below parity) |
|
|
88
|
+
| `children recursion (cold)` | 0.27x | structural | tracked (below parity) |
|
|
89
|
+
| `plan records (typed)` | 0.79x | data | informational |
|
|
90
|
+
<!-- SCOREBOARD:END -->
|
|
91
|
+
|
|
92
|
+
The open rows are the known structural gap: every node the facade
|
|
93
|
+
hands a consumer is a contract-carrying wrapper with its own
|
|
94
|
+
identity/invalidation state, while nokogiri hands out thin handles.
|
|
95
|
+
Closing them needs engine-side construction/walk faces (leptris
|
|
96
|
+
C contract work), not more facade tuning. Facade-side wins already
|
|
97
|
+
landed here: single-crossing `add_element` construction, native
|
|
98
|
+
`set_binding_text` without a binding-twin mint per write, and the
|
|
99
|
+
generation memo no longer writing on every `children` read.
|
|
100
|
+
|
|
101
|
+
Numbers move by a few percent between runs; the lock's 10% tolerance
|
|
102
|
+
is the regression tripwire, not a claim of precision. The committed
|
|
103
|
+
baseline is a reference measured on a shared machine — regenerate it
|
|
104
|
+
on a quiet machine (the `performance` workflow uploads its measured
|
|
105
|
+
`scoreboard.json` as an artifact) before treating a lock failure as
|
|
106
|
+
a regression.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"protocol": {
|
|
3
|
+
"measured": "2026-10-20T14:53:54Z",
|
|
4
|
+
"ruby": "3.4.8",
|
|
5
|
+
"adapter": "leptris",
|
|
6
|
+
"adapter_version": "1.9.374.0",
|
|
7
|
+
"nokogiri": "1.19.4",
|
|
8
|
+
"reps": 9,
|
|
9
|
+
"warmup": 2,
|
|
10
|
+
"clock": "CLOCK_PROCESS_CPUTIME_ID",
|
|
11
|
+
"load": 34.01
|
|
12
|
+
},
|
|
13
|
+
"rows": [
|
|
14
|
+
{
|
|
15
|
+
"row": "parse",
|
|
16
|
+
"kind": "parity",
|
|
17
|
+
"parity": true,
|
|
18
|
+
"baseline_us": 677.0,
|
|
19
|
+
"candidate_us": 261.0,
|
|
20
|
+
"ratio": 2.594,
|
|
21
|
+
"baseline_allocs": 6,
|
|
22
|
+
"candidate_allocs": 18
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"row": "serialize",
|
|
26
|
+
"kind": "parity",
|
|
27
|
+
"parity": true,
|
|
28
|
+
"baseline_us": 474.0,
|
|
29
|
+
"candidate_us": 351.0,
|
|
30
|
+
"ratio": 1.35,
|
|
31
|
+
"baseline_allocs": 30,
|
|
32
|
+
"candidate_allocs": 13
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"row": "xpath //field (count)",
|
|
36
|
+
"kind": "parity",
|
|
37
|
+
"parity": true,
|
|
38
|
+
"baseline_us": 132.0,
|
|
39
|
+
"candidate_us": 110.0,
|
|
40
|
+
"ratio": 1.2,
|
|
41
|
+
"baseline_allocs": 12,
|
|
42
|
+
"candidate_allocs": 9
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"row": "xpath //field (each)",
|
|
46
|
+
"kind": "structural",
|
|
47
|
+
"parity": false,
|
|
48
|
+
"baseline_us": 276.0,
|
|
49
|
+
"candidate_us": 800.0,
|
|
50
|
+
"ratio": 0.345,
|
|
51
|
+
"baseline_allocs": 1212,
|
|
52
|
+
"candidate_allocs": 12
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"row": "attr pairs listing",
|
|
56
|
+
"kind": "parity",
|
|
57
|
+
"parity": true,
|
|
58
|
+
"baseline_us": 310.0,
|
|
59
|
+
"candidate_us": 38.0,
|
|
60
|
+
"ratio": 8.158,
|
|
61
|
+
"baseline_allocs": 3300,
|
|
62
|
+
"candidate_allocs": 0
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"row": "build add_element",
|
|
66
|
+
"kind": "structural",
|
|
67
|
+
"parity": false,
|
|
68
|
+
"baseline_us": 3434.0,
|
|
69
|
+
"candidate_us": 5744.0,
|
|
70
|
+
"ratio": 0.598,
|
|
71
|
+
"baseline_allocs": 20358,
|
|
72
|
+
"candidate_allocs": 11062
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"row": "walk+read (warm)",
|
|
76
|
+
"kind": "structural",
|
|
77
|
+
"parity": false,
|
|
78
|
+
"baseline_us": 1101.0,
|
|
79
|
+
"candidate_us": 1431.0,
|
|
80
|
+
"ratio": 0.769,
|
|
81
|
+
"baseline_allocs": 4503,
|
|
82
|
+
"candidate_allocs": 2
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"row": "walk+read (cold)",
|
|
86
|
+
"kind": "structural",
|
|
87
|
+
"parity": false,
|
|
88
|
+
"baseline_us": 1915.0,
|
|
89
|
+
"candidate_us": 8590.0,
|
|
90
|
+
"ratio": 0.223,
|
|
91
|
+
"baseline_allocs": 6010,
|
|
92
|
+
"candidate_allocs": 8730
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"row": "children recursion (cold)",
|
|
96
|
+
"kind": "structural",
|
|
97
|
+
"parity": false,
|
|
98
|
+
"baseline_us": 2293.0,
|
|
99
|
+
"candidate_us": 8595.0,
|
|
100
|
+
"ratio": 0.267,
|
|
101
|
+
"baseline_allocs": 5710,
|
|
102
|
+
"candidate_allocs": 7230
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"row": "plan records (typed)",
|
|
106
|
+
"kind": "data",
|
|
107
|
+
"parity": false,
|
|
108
|
+
"baseline_us": 2401.0,
|
|
109
|
+
"candidate_us": 3038.0,
|
|
110
|
+
"ratio": 0.79,
|
|
111
|
+
"baseline_allocs": 8111,
|
|
112
|
+
"candidate_allocs": 13231
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|