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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 957697bcb855cea040ac0d8b2f202a7cd8fd230482137602fcf7d50fc2712ebb
4
- data.tar.gz: 22815ac3e9920a8939b0076f3b4222a154e0420d4fe1a21d9b7e56bd9b0818b8
3
+ metadata.gz: 2945a0f85059a2979b59e3623e208fcc7bbd0195b2e00b581502adb5fa9f76ac
4
+ data.tar.gz: a5ca2152292ba794be5bc6edd766e36bf769b86fa63ce235a396645245b38bf7
5
5
  SHA512:
6
- metadata.gz: 422b076bb191e01b27693af02a66d4e985f574dbcc49451c9af395c1905f9cabfdb2faf0e1b15303a5444c17a8fba98e70e5bea7d5c61f1f152d9fa09a550329
7
- data.tar.gz: 2d75b66d322414ea8c99b79fe1ed78c7aa758b90b7f5b7f56a685e9f861bca12d6f641803aa04ced575a812677a085619bd40ee435963b035cdbe005a36d1b55
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.81"
4
+ VERSION = "0.5.82"
5
5
  end
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.81
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