moxml 0.5.81 → 0.5.82
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/Rakefile +8 -0
- data/benchmark/sax_bench.rb +99 -0
- data/lib/moxml/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2945a0f85059a2979b59e3623e208fcc7bbd0195b2e00b581502adb5fa9f76ac
|
|
4
|
+
data.tar.gz: a5ca2152292ba794be5bc6edd766e36bf769b86fa63ce235a396645245b38bf7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c57a2679fa6b1230ba4965f868c40de1eb98a8a4dac5dfe52a24a81f131d4ebb566707150b6d04e1f8b25d7e08bd284eae75d848b4488a0eed9c999b25662d5
|
|
7
|
+
data.tar.gz: 76107d50a3f3bfa76d2926931cbc54d49aa7e7e14d68f0aa932fb93513597d254f5063daf0341780bf9a2783472a884444b884fe50fa16e2248f08e0dcc68978
|
data/Rakefile
CHANGED
|
@@ -263,6 +263,14 @@ namespace :benchmark do
|
|
|
263
263
|
sh "bundle exec ruby benchmark/plan_bench.rb"
|
|
264
264
|
end
|
|
265
265
|
|
|
266
|
+
# SAX bench row (leptris#1298 / #279): the bulk record drain vs
|
|
267
|
+
# the callback Recorder. With LEPTRIS_BENCH_LOCK=1 (CI) it exits 1
|
|
268
|
+
# unless records-walk allocations stay under half the recorder's.
|
|
269
|
+
desc "SAX parse benchmark: record drain vs callback recorder"
|
|
270
|
+
task :sax do
|
|
271
|
+
sh "bundle exec ruby benchmark/sax_bench.rb"
|
|
272
|
+
end
|
|
273
|
+
|
|
266
274
|
desc "Generate adapter benchmark report"
|
|
267
275
|
task :report do
|
|
268
276
|
ruby "benchmarks/generate_report.rb"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SAX bench row (leptris#1298 follow-up / moxml#279 item 4): the
|
|
4
|
+
# bulk record drain vs the callback Recorder on the canon parse-lane
|
|
5
|
+
# shape. Run via `rake benchmark:sax`; with LEPTRIS_BENCH_LOCK=1
|
|
6
|
+
# (CI) it exits 1 unless the drain stays materially cheaper than the
|
|
7
|
+
# recorder — records-walk allocations must land under half the
|
|
8
|
+
# recorder's, so the win stays visible and a regression re-opens
|
|
9
|
+
# the lane.
|
|
10
|
+
require "moxml"
|
|
11
|
+
|
|
12
|
+
item = "<item n=\"1\" kind=\"k\" id=\"i1\">value text</item>"
|
|
13
|
+
DOC = "<r>#{item * 225}<t>tail</t></r>".freeze # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
14
|
+
DOCS = [DOC, DOC].freeze # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
15
|
+
|
|
16
|
+
module SaxBenchHandlers
|
|
17
|
+
class NullHandler < Moxml::SAX::Handler
|
|
18
|
+
def on_start_element(_name, _attrs = {}, _namespaces = {}); end
|
|
19
|
+
|
|
20
|
+
def on_end_element(_name); end
|
|
21
|
+
|
|
22
|
+
def on_characters(_text); end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class RecordWalkHandler < Moxml::SAX::Handler
|
|
26
|
+
attr_reader :elements
|
|
27
|
+
|
|
28
|
+
def initialize
|
|
29
|
+
super
|
|
30
|
+
@elements = 0
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The hot-loop shape: walk the records, materialize one name per
|
|
34
|
+
# element (the #1298 target — consumer-chosen allocations).
|
|
35
|
+
def on_sax_records(table)
|
|
36
|
+
i = 0
|
|
37
|
+
while i < table.count
|
|
38
|
+
@elements += 1 if table.kind(i).zero? && table.view(i)
|
|
39
|
+
i += 1
|
|
40
|
+
end
|
|
41
|
+
:claimed
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
CTX = Moxml.new(:leptris).freeze # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
47
|
+
BRIDGE = Moxml::Adapter::Leptris::LeptrisSAXBridge # rubocop:disable Lint/ConstantDefinitionInBlock
|
|
48
|
+
|
|
49
|
+
def allocations
|
|
50
|
+
GC.start
|
|
51
|
+
before = GC.stat(:total_allocated_objects)
|
|
52
|
+
GC.disable
|
|
53
|
+
yield
|
|
54
|
+
GC.enable
|
|
55
|
+
GC.stat(:total_allocated_objects) - before
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def cpu_micros
|
|
59
|
+
GC.start
|
|
60
|
+
t0 = Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :microsecond)
|
|
61
|
+
yield
|
|
62
|
+
Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :microsecond) - t0
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# warm both lanes
|
|
66
|
+
handler = SaxBenchHandlers::NullHandler.new
|
|
67
|
+
3.times { DOCS.each { |doc| Moxml::Adapter::Leptris.sax_parse(doc, handler) } }
|
|
68
|
+
3.times { DOCS.each { |doc| Leptris::XML::SAX::Parser.new(BRIDGE.new(handler)).parse(doc) } }
|
|
69
|
+
walker = SaxBenchHandlers::RecordWalkHandler.new
|
|
70
|
+
3.times { DOCS.each { |doc| Moxml::Adapter::Leptris.sax_parse(doc, walker) } }
|
|
71
|
+
|
|
72
|
+
recorder_allocs = allocations do
|
|
73
|
+
DOCS.each { |doc| Leptris::XML::SAX::Parser.new(BRIDGE.new(handler)).parse(doc) }
|
|
74
|
+
end
|
|
75
|
+
replay_allocs = allocations do
|
|
76
|
+
DOCS.each { |doc| Moxml::Adapter::Leptris.sax_parse(doc, handler) }
|
|
77
|
+
end
|
|
78
|
+
walk_allocs = allocations do
|
|
79
|
+
DOCS.each { |doc| Moxml::Adapter::Leptris.sax_parse(doc, walker) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
replay_time = cpu_micros { 5.times { DOCS.each { |doc| Moxml::Adapter::Leptris.sax_parse(doc, handler) } } }
|
|
83
|
+
recorder_time = cpu_micros { 5.times { DOCS.each { |doc| Leptris::XML::SAX::Parser.new(BRIDGE.new(handler)).parse(doc) } } }
|
|
84
|
+
walk_time = cpu_micros { 5.times { DOCS.each { |doc| Moxml::Adapter::Leptris.sax_parse(doc, walker) } } }
|
|
85
|
+
|
|
86
|
+
puts format("recorder %<allocs>6d allocs %<time>6dµs", allocs: recorder_allocs, time: recorder_time / 5)
|
|
87
|
+
puts format("drain replay %<allocs>6d allocs %<time>6dµs", allocs: replay_allocs, time: replay_time / 5)
|
|
88
|
+
puts format("drain records-walk %<allocs>6d allocs %<time>6dµs", allocs: walk_allocs, time: walk_time / 5)
|
|
89
|
+
puts "(#{walker.elements} elements walked cumulatively; 452 per rep)"
|
|
90
|
+
|
|
91
|
+
if ENV["LEPTRIS_BENCH_LOCK"]
|
|
92
|
+
if walk_allocs >= recorder_allocs / 2
|
|
93
|
+
warn "LEPTRIS_BENCH_LOCK: records-walk allocs (#{walk_allocs}) " \
|
|
94
|
+
"not under half the recorder's (#{recorder_allocs}) — the " \
|
|
95
|
+
"#1298 win regressed"
|
|
96
|
+
exit 1
|
|
97
|
+
end
|
|
98
|
+
puts "lock: records-walk under half the recorder's allocations ✓"
|
|
99
|
+
end
|
data/lib/moxml/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.82
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -41,6 +41,7 @@ files:
|
|
|
41
41
|
- Rakefile
|
|
42
42
|
- benchmark/pipeline_bench.rb
|
|
43
43
|
- benchmark/plan_bench.rb
|
|
44
|
+
- benchmark/sax_bench.rb
|
|
44
45
|
- benchmarks/.gitignore
|
|
45
46
|
- benchmarks/generate_report.rb
|
|
46
47
|
- bin/console
|