serialbench 0.2.0 → 0.3.1

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/scripts/push-to-data.sh +65 -0
  3. data/.github/workflows/benchmark.yml +106 -160
  4. data/.github/workflows/release.yml +68 -13
  5. data/Gemfile +1 -1
  6. data/config/benchmarks/full-json.yml +25 -0
  7. data/config/benchmarks/full-toml.yml +25 -0
  8. data/config/benchmarks/full-xml.yml +26 -0
  9. data/config/benchmarks/full-yaml.yml +25 -0
  10. data/config/benchmarks/full.yml +9 -4
  11. data/lib/serialbench/benchmark_runner.rb +20 -23
  12. data/lib/serialbench/cli/benchmark_cli.rb +1 -1
  13. data/lib/serialbench/cli.rb +1 -8
  14. data/lib/serialbench/models/benchmark_result.rb +2 -0
  15. data/lib/serialbench/serializers/base_serializer.rb +14 -2
  16. data/lib/serialbench/serializers/xml/base_xml_serializer.rb +6 -10
  17. data/lib/serialbench/serializers/xml/leptris_serializer.rb +15 -8
  18. data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +2 -7
  19. data/lib/serialbench/serializers/xml/oga_serializer.rb +4 -0
  20. data/lib/serialbench/version.rb +1 -1
  21. data/lib/serialbench.rb +1 -1
  22. metadata +8 -38
  23. data/lib/serialbench/templates/assets/css/benchmark_report.css +0 -535
  24. data/lib/serialbench/templates/assets/css/format_based.css +0 -474
  25. data/lib/serialbench/templates/assets/css/themes.css +0 -589
  26. data/lib/serialbench/templates/assets/js/chart_helpers.js +0 -411
  27. data/lib/serialbench/templates/assets/js/dashboard.js +0 -795
  28. data/lib/serialbench/templates/assets/js/navigation.js +0 -142
  29. data/lib/serialbench/templates/base.liquid +0 -49
  30. data/lib/serialbench/templates/format_based.liquid +0 -507
  31. data/lib/serialbench/templates/partials/chart_section.liquid +0 -4
  32. data/site/.gitignore +0 -5
  33. data/site/README.md +0 -32
  34. data/site/astro.config.mjs +0 -12
  35. data/site/package-lock.json +0 -6160
  36. data/site/package.json +0 -22
  37. data/site/public/favicon.svg +0 -4
  38. data/site/scripts/gen-sample-data.mjs +0 -154
  39. data/site/src/components/AvailabilityMatrix.astro +0 -61
  40. data/site/src/components/CalibratedLeaderboard.vue +0 -134
  41. data/site/src/components/CitationBox.vue +0 -50
  42. data/site/src/components/DashboardConsole.vue +0 -193
  43. data/site/src/components/FeaturesTable.astro +0 -97
  44. data/site/src/components/MemoryPanel.vue +0 -44
  45. data/site/src/components/OpsChart.vue +0 -135
  46. data/site/src/config.ts +0 -18
  47. data/site/src/layouts/Layout.astro +0 -85
  48. data/site/src/lib/channels.ts +0 -24
  49. data/site/src/lib/dashboard.ts +0 -269
  50. data/site/src/pages/index.astro +0 -44
  51. data/site/src/pages/library/[slug].astro +0 -128
  52. data/site/src/pages/methodology.astro +0 -55
  53. data/site/src/styles/global.css +0 -103
  54. data/site/tsconfig.json +0 -5
@@ -15,15 +15,20 @@ formats:
15
15
  - yaml
16
16
  - toml
17
17
 
18
+ # Trimmed from 20/5/2 (warmup 3): a healthy leg took ~70 minutes at that
19
+ # setting, which both inflates weekly cost and leaves legs exposed to
20
+ # runner-eviction flakiness. 10/3/1 with warmup 2 halves runtime with
21
+ # acceptable added noise.
18
22
  iterations:
19
- small: 20
20
- medium: 5
21
- large: 2
23
+ small: 10
24
+ medium: 3
25
+ large: 1
22
26
 
23
27
  operations:
24
28
  - parse
25
29
  - generate
26
30
  - streaming
31
+ - xpath
27
32
  - memory
28
33
 
29
- warmup: 3
34
+ warmup: 2
@@ -24,6 +24,19 @@ module Serialbench
24
24
  load_test_data
25
25
  end
26
26
 
27
+ # Each operation maps to a lambda. Adding an operation = one entry.
28
+ OPERATIONS = {
29
+ 'parsing' => ->(s, data) { s.parse(data) },
30
+ 'generation' => ->(s, data) { s.generate(s.parse(data)) },
31
+ 'xpath' => lambda { |s, data|
32
+ doc = s.parse(data)
33
+ s.xpath_query(doc, '//book')
34
+ s.xpath_query(doc, "//book[@id='101']")
35
+ s.xpath_query(doc, '//book[price > 30]/title')
36
+ },
37
+ 'streaming' => ->(s, data) { s.stream_parse(data) { |_event, _data| } },
38
+ }.freeze
39
+
27
40
  def run_all_benchmarks
28
41
  puts 'Serialbench - Running comprehensive serialization performance tests'
29
42
  puts '=' * 70
@@ -32,34 +45,18 @@ module Serialbench
32
45
  puts "Test data sizes: #{@test_data.keys.join(', ')}"
33
46
  puts
34
47
 
48
+ results = {}
49
+ OPERATIONS.each do |name, handler|
50
+ results[name.to_sym] = run_benchmark_type(name, name, &handler)
51
+ end
52
+ results[:memory] = run_memory_benchmarks
53
+
35
54
  Models::BenchmarkResult.new(
36
55
  serializers: Serializers.information,
37
- parsing: run_parsing_benchmarks,
38
- generation: run_generation_benchmarks,
39
- memory: run_memory_benchmarks,
40
- streaming: run_streaming_benchmarks
56
+ **results
41
57
  )
42
58
  end
43
59
 
44
- def run_parsing_benchmarks
45
- run_benchmark_type('parsing', 'parse') do |serializer, data|
46
- serializer.parse(data)
47
- end
48
- end
49
-
50
- def run_generation_benchmarks
51
- run_benchmark_type('generation', 'generation') do |serializer, data|
52
- document = serializer.parse(data)
53
- serializer.generate(document)
54
- end
55
- end
56
-
57
- def run_streaming_benchmarks
58
- run_benchmark_type('streaming', 'stream parse') do |serializer, data|
59
- serializer.stream_parse(data) { |event, data| }
60
- end
61
- end
62
-
63
60
  def run_memory_benchmarks
64
61
  puts "\nRunning memory usage benchmarks..."
65
62
  return [] unless defined?(::MemoryProfiler)
@@ -190,7 +190,7 @@ module Serialbench
190
190
  say "🏗️ Generating HTML site for result: #{result_path}", :green
191
191
 
192
192
  # Use the unified site generator for results
193
- Serialbench::SiteGenerator.generate_for_result(result, options[:output_dir])
193
+ puts 'Site generation moved to serialbench.github.io'
194
194
 
195
195
  say '✅ HTML site generated successfully!', :green
196
196
  say "Site location: #{options[:output_dir]}", :cyan
@@ -4,9 +4,9 @@ require 'thor'
4
4
  require_relative 'cli/base_cli'
5
5
  require_relative 'cli/environment_cli'
6
6
  require_relative 'cli/benchmark_cli'
7
- require_relative 'cli/resultset_cli'
8
7
  require_relative 'cli/ruby_build_cli'
9
8
  require_relative 'cli/validate_cli'
9
+ require_relative 'cli/resultset_cli'
10
10
 
11
11
  module Serialbench
12
12
  # Main CLI entry point for the new object-oriented command structure
@@ -17,9 +17,6 @@ module Serialbench
17
17
  desc 'benchmark SUBCOMMAND', 'Manage individual benchmark runs'
18
18
  subcommand 'benchmark', Serialbench::Cli::BenchmarkCli
19
19
 
20
- desc 'resultset SUBCOMMAND', 'Manage benchmark resultsets (collections of runs)'
21
- subcommand 'resultset', Serialbench::Cli::ResultsetCli
22
-
23
20
  desc 'ruby_build SUBCOMMAND', 'Manage Ruby-Build definitions for validation'
24
21
  subcommand 'ruby_build', Serialbench::Cli::RubyBuildCli
25
22
 
@@ -45,7 +42,6 @@ module Serialbench
45
42
  COMMANDS:
46
43
  environment Manage benchmark environments (Docker, ASDF, Local)
47
44
  benchmark Manage individual benchmark runs
48
- resultset Manage benchmark resultsets (collections of runs)
49
45
  ruby-build Manage Ruby-Build definitions for validation
50
46
  version Show version information
51
47
  help Show this help message
@@ -63,12 +59,9 @@ module Serialbench
63
59
  serialbench benchmark execute my-benchmark.yml
64
60
 
65
61
  # Create a result set for comparison
66
- serialbench resultset create comparison-set
67
- serialbench resultset add-result comparison-set results/my-benchmark
68
62
 
69
63
  # Generate static sites
70
64
  serialbench benchmark build-site results/my-benchmark
71
- serialbench resultset build-site resultsets/comparison-set
72
65
 
73
66
  For detailed help on any command, use:
74
67
  serialbench COMMAND help
@@ -68,6 +68,7 @@ module Serialbench
68
68
  attribute :generation, IterationPerformance, collection: true
69
69
  attribute :memory, MemoryPerformance, collection: true
70
70
  attribute :streaming, IterationPerformance, collection: true
71
+ attribute :xpath, IterationPerformance, collection: true
71
72
 
72
73
  key_value do
73
74
  map 'serializers', to: :serializers
@@ -75,6 +76,7 @@ module Serialbench
75
76
  map 'generation', to: :generation
76
77
  map 'memory', to: :memory
77
78
  map 'streaming', to: :streaming
79
+ map 'xpath', to: :xpath
78
80
  end
79
81
  end
80
82
  end
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  # frozen_string_literal: true
2
4
 
3
5
  require 'singleton'
@@ -33,9 +35,19 @@ module Serialbench
33
35
  result
34
36
  end
35
37
 
38
+ # Capabilities: a Set of symbols declaring what this adapter can do.
39
+ # Subclasses override to add symbols; the base handles every query.
40
+ # This replaces the 12+ individual supports_X? predicates.
41
+ def capabilities
42
+ Set.new(%i[dom parse generate])
43
+ end
44
+
45
+ def supports?(capability)
46
+ capabilities.include?(capability)
47
+ end
48
+
36
49
  def supports_streaming?
37
- # Override in subclasses that support streaming
38
- false
50
+ supports?(:sax) || supports?(:streaming)
39
51
  end
40
52
 
41
53
  def require_library(library_name)
@@ -23,21 +23,17 @@ module Serialbench
23
23
  generate(document, options)
24
24
  end
25
25
 
26
- # XML-specific features
26
+ # XML-specific features derive from the capability set
27
27
  def features
28
28
  {
29
- xpath: supports_xpath?,
30
- namespaces: supports_namespaces?,
31
- validation: supports_validation?,
32
- streaming: supports_streaming?,
33
- stax: supports_stax?
29
+ xpath: supports?(:xpath),
30
+ namespaces: supports?(:namespaces),
31
+ validation: supports?(:validation),
32
+ streaming: supports?(:sax) || supports?(:streaming),
33
+ stax: supports?(:stax)
34
34
  }
35
35
  end
36
36
 
37
- def supports_stax?
38
- false
39
- end
40
-
41
37
  def supports_generation?
42
38
  true
43
39
  end
@@ -12,11 +12,13 @@ module Serialbench
12
12
 
13
13
  def parse(xml_string)
14
14
  require 'leptris'
15
+ require 'leptris/xml'
15
16
  Leptris::XML.parse(xml_string)
16
17
  end
17
18
 
18
19
  def generate(data)
19
20
  require 'leptris'
21
+ require 'leptris/xml'
20
22
  if data.is_a?(Leptris::XML::Document) || data.is_a?(Leptris::XML::Node)
21
23
  data.to_xml(indent: 2)
22
24
  else
@@ -26,6 +28,7 @@ module Serialbench
26
28
 
27
29
  def parse_streaming(xml_string, &block)
28
30
  require 'leptris'
31
+ require 'leptris/xml'
29
32
 
30
33
  handler = StreamingHandler.new(&block)
31
34
  parser = Leptris::XML::SAX::Parser.new(handler)
@@ -37,24 +40,27 @@ module Serialbench
37
40
  true
38
41
  end
39
42
 
40
- def supports_xpath?
41
- true
43
+ def capabilities
44
+ super | Set.new(%i[xpath namespaces sax stax])
45
+ end
46
+
47
+ def xpath_query(document, expression)
48
+ require 'leptris'
49
+ require 'leptris/xml'
50
+ result = document.xpath(expression)
51
+ result.size
42
52
  end
43
53
 
44
54
  # leptris-ruby >= 1.6 exposes Leptris::XML::Pull, a StAX-style
45
55
  # cursor (one event per #next). Declared by gem version so the
46
56
  # check never triggers the FFI library load.
47
- def supports_stax?
48
- spec = Gem.loaded_specs['leptris'] || Gem::Specification.find_by_name('leptris')
49
- !spec.nil? && spec.version >= Gem::Version.new('1.6.0')
50
- rescue Gem::LoadError
51
- false
52
- end
57
+
53
58
 
54
59
  def version
55
60
  return 'unknown' unless available?
56
61
 
57
62
  require 'leptris'
63
+ require 'leptris/xml'
58
64
  Leptris::VERSION
59
65
  end
60
66
 
@@ -70,6 +76,7 @@ module Serialbench
70
76
 
71
77
  @available = begin
72
78
  require 'leptris'
79
+ require 'leptris/xml'
73
80
  Leptris::XML.parse('<probe/>')
74
81
  true
75
82
  rescue StandardError, LoadError
@@ -38,13 +38,8 @@ module Serialbench
38
38
  handler.elements_processed
39
39
  end
40
40
 
41
- def supports_xpath?
42
- true
43
- end
44
-
45
- # The binding exposes a pull-parser cursor (XML::Reader)
46
- def supports_stax?
47
- true
41
+ def capabilities
42
+ super | Set.new(%i[xpath namespaces stax])
48
43
  end
49
44
 
50
45
  def supports_streaming?
@@ -42,6 +42,10 @@ module Serialbench
42
42
  true
43
43
  end
44
44
 
45
+ def xpath_query(document, expression)
46
+ document.xpath(expression).size
47
+ end
48
+
45
49
  def supports_streaming?
46
50
  true
47
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Serialbench
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.1'
5
5
  end
data/lib/serialbench.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'serialbench/version'
4
+ require_relative 'serialbench/site_generator'
4
5
  require_relative 'serialbench/serializers'
5
6
  require_relative 'serialbench/benchmark_runner'
6
7
  require_relative 'serialbench/cli'
7
8
  require_relative 'serialbench/memory_profiler'
8
9
  require_relative 'serialbench/models'
9
- require_relative 'serialbench/site_generator'
10
10
 
11
11
  module Serialbench
12
12
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serialbench
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2026-08-24 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: benchmark-ips
@@ -271,6 +270,7 @@ executables:
271
270
  extensions: []
272
271
  extra_rdoc_files: []
273
272
  files:
273
+ - ".github/scripts/push-to-data.sh"
274
274
  - ".github/workflows/benchmark.yml"
275
275
  - ".github/workflows/rake.yml"
276
276
  - ".github/workflows/release.yml"
@@ -282,6 +282,10 @@ files:
282
282
  - Gemfile
283
283
  - README.adoc
284
284
  - Rakefile
285
+ - config/benchmarks/full-json.yml
286
+ - config/benchmarks/full-toml.yml
287
+ - config/benchmarks/full-xml.yml
288
+ - config/benchmarks/full-yaml.yml
285
289
  - config/benchmarks/full.yml
286
290
  - config/benchmarks/short.yml
287
291
  - config/environments/asdf-ruby-3.2.yml
@@ -347,41 +351,9 @@ files:
347
351
  - lib/serialbench/serializers/yaml/psych_serializer.rb
348
352
  - lib/serialbench/serializers/yaml/syck_serializer.rb
349
353
  - lib/serialbench/site_generator.rb
350
- - lib/serialbench/templates/assets/css/benchmark_report.css
351
- - lib/serialbench/templates/assets/css/format_based.css
352
- - lib/serialbench/templates/assets/css/themes.css
353
- - lib/serialbench/templates/assets/js/chart_helpers.js
354
- - lib/serialbench/templates/assets/js/dashboard.js
355
- - lib/serialbench/templates/assets/js/navigation.js
356
- - lib/serialbench/templates/base.liquid
357
- - lib/serialbench/templates/format_based.liquid
358
- - lib/serialbench/templates/partials/chart_section.liquid
359
354
  - lib/serialbench/version.rb
360
355
  - lib/serialbench/yaml_validator.rb
361
356
  - serialbench.gemspec
362
- - site/.gitignore
363
- - site/README.md
364
- - site/astro.config.mjs
365
- - site/package-lock.json
366
- - site/package.json
367
- - site/public/favicon.svg
368
- - site/scripts/gen-sample-data.mjs
369
- - site/src/components/AvailabilityMatrix.astro
370
- - site/src/components/CalibratedLeaderboard.vue
371
- - site/src/components/CitationBox.vue
372
- - site/src/components/DashboardConsole.vue
373
- - site/src/components/FeaturesTable.astro
374
- - site/src/components/MemoryPanel.vue
375
- - site/src/components/OpsChart.vue
376
- - site/src/config.ts
377
- - site/src/layouts/Layout.astro
378
- - site/src/lib/channels.ts
379
- - site/src/lib/dashboard.ts
380
- - site/src/pages/index.astro
381
- - site/src/pages/library/[slug].astro
382
- - site/src/pages/methodology.astro
383
- - site/src/styles/global.css
384
- - site/tsconfig.json
385
357
  homepage: https://github.com/metanorma/serialbench
386
358
  licenses:
387
359
  - BSD-2-Clause
@@ -389,7 +361,6 @@ metadata:
389
361
  homepage_uri: https://github.com/metanorma/serialbench
390
362
  source_code_uri: https://github.com/metanorma/serialbench
391
363
  bug_tracker_uri: https://github.com/metanorma/serialbench/issues
392
- post_install_message:
393
364
  rdoc_options: []
394
365
  require_paths:
395
366
  - lib
@@ -404,8 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
404
375
  - !ruby/object:Gem::Version
405
376
  version: '0'
406
377
  requirements: []
407
- rubygems_version: 3.5.22
408
- signing_key:
378
+ rubygems_version: 3.6.9
409
379
  specification_version: 4
410
380
  summary: Comprehensive serialization benchmarking tool for Ruby
411
381
  test_files: []