serialbench 0.1.1 → 0.1.2

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/benchmark.yml +13 -5
  3. data/.github/workflows/docker.yml +35 -9
  4. data/.github/workflows/rake.yml +15 -0
  5. data/Gemfile +2 -1
  6. data/README.adoc +267 -1129
  7. data/Rakefile +0 -55
  8. data/config/benchmarks/full.yml +29 -0
  9. data/config/benchmarks/short.yml +26 -0
  10. data/config/environments/asdf-ruby-3.2.yml +8 -0
  11. data/config/environments/asdf-ruby-3.3.yml +8 -0
  12. data/config/environments/docker-ruby-3.0.yml +9 -0
  13. data/config/environments/docker-ruby-3.1.yml +9 -0
  14. data/config/environments/docker-ruby-3.2.yml +9 -0
  15. data/config/environments/docker-ruby-3.3.yml +9 -0
  16. data/config/environments/docker-ruby-3.4.yml +9 -0
  17. data/docker/Dockerfile.alpine +33 -0
  18. data/docker/{Dockerfile.benchmark → Dockerfile.ubuntu} +4 -3
  19. data/docker/README.md +2 -2
  20. data/exe/serialbench +1 -1
  21. data/lib/serialbench/benchmark_runner.rb +261 -423
  22. data/lib/serialbench/cli/base_cli.rb +51 -0
  23. data/lib/serialbench/cli/benchmark_cli.rb +380 -0
  24. data/lib/serialbench/cli/environment_cli.rb +181 -0
  25. data/lib/serialbench/cli/resultset_cli.rb +215 -0
  26. data/lib/serialbench/cli/ruby_build_cli.rb +238 -0
  27. data/lib/serialbench/cli.rb +58 -601
  28. data/lib/serialbench/config_manager.rb +140 -0
  29. data/lib/serialbench/models/benchmark_config.rb +63 -0
  30. data/lib/serialbench/models/benchmark_result.rb +45 -0
  31. data/lib/serialbench/models/environment_config.rb +71 -0
  32. data/lib/serialbench/models/platform.rb +59 -0
  33. data/lib/serialbench/models/result.rb +53 -0
  34. data/lib/serialbench/models/result_set.rb +71 -0
  35. data/lib/serialbench/models/result_store.rb +108 -0
  36. data/lib/serialbench/models.rb +54 -0
  37. data/lib/serialbench/ruby_build_manager.rb +153 -0
  38. data/lib/serialbench/runners/asdf_runner.rb +296 -0
  39. data/lib/serialbench/runners/base.rb +32 -0
  40. data/lib/serialbench/runners/docker_runner.rb +142 -0
  41. data/lib/serialbench/serializers/base_serializer.rb +8 -16
  42. data/lib/serialbench/serializers/json/base_json_serializer.rb +4 -4
  43. data/lib/serialbench/serializers/json/json_serializer.rb +0 -2
  44. data/lib/serialbench/serializers/json/oj_serializer.rb +0 -2
  45. data/lib/serialbench/serializers/json/yajl_serializer.rb +0 -2
  46. data/lib/serialbench/serializers/toml/base_toml_serializer.rb +5 -3
  47. data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +0 -2
  48. data/lib/serialbench/serializers/toml/tomlib_serializer.rb +0 -2
  49. data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +56 -0
  50. data/lib/serialbench/serializers/xml/base_xml_serializer.rb +4 -9
  51. data/lib/serialbench/serializers/xml/libxml_serializer.rb +0 -2
  52. data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +0 -2
  53. data/lib/serialbench/serializers/xml/oga_serializer.rb +0 -2
  54. data/lib/serialbench/serializers/xml/ox_serializer.rb +0 -2
  55. data/lib/serialbench/serializers/xml/rexml_serializer.rb +0 -2
  56. data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +5 -1
  57. data/lib/serialbench/serializers/yaml/syck_serializer.rb +59 -22
  58. data/lib/serialbench/serializers.rb +23 -6
  59. data/lib/serialbench/site_generator.rb +105 -0
  60. data/lib/serialbench/templates/assets/css/benchmark_report.css +535 -0
  61. data/lib/serialbench/templates/assets/css/format_based.css +526 -0
  62. data/lib/serialbench/templates/assets/css/themes.css +588 -0
  63. data/lib/serialbench/templates/assets/js/chart_helpers.js +381 -0
  64. data/lib/serialbench/templates/assets/js/dashboard.js +796 -0
  65. data/lib/serialbench/templates/assets/js/navigation.js +142 -0
  66. data/lib/serialbench/templates/base.liquid +49 -0
  67. data/lib/serialbench/templates/format_based.liquid +279 -0
  68. data/lib/serialbench/templates/partials/chart_section.liquid +4 -0
  69. data/lib/serialbench/version.rb +1 -1
  70. data/lib/serialbench.rb +2 -31
  71. data/serialbench.gemspec +4 -1
  72. metadata +86 -16
  73. data/config/ci.yml +0 -22
  74. data/config/full.yml +0 -30
  75. data/docker/run-benchmarks.sh +0 -356
  76. data/lib/serialbench/chart_generator.rb +0 -821
  77. data/lib/serialbench/result_formatter.rb +0 -182
  78. data/lib/serialbench/result_merger.rb +0 -1201
  79. data/lib/serialbench/serializers/xml/base_parser.rb +0 -69
  80. data/lib/serialbench/serializers/xml/libxml_parser.rb +0 -98
  81. data/lib/serialbench/serializers/xml/nokogiri_parser.rb +0 -111
  82. data/lib/serialbench/serializers/xml/oga_parser.rb +0 -85
  83. data/lib/serialbench/serializers/xml/ox_parser.rb +0 -64
  84. data/lib/serialbench/serializers/xml/rexml_parser.rb +0 -129
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
- require 'csv'
5
-
6
- module Serialbench
7
- class ResultFormatter
8
- def initialize(results)
9
- @results = results
10
- end
11
-
12
- def to_json(pretty: true)
13
- if pretty
14
- JSON.pretty_generate(@results)
15
- else
16
- JSON.generate(@results)
17
- end
18
- end
19
-
20
- def to_csv
21
- return '' unless @results && @results[:dom_parsing]
22
-
23
- csv_data = []
24
-
25
- # Header
26
- csv_data << ['Category', 'File Size', 'Parser', 'Time (ms)', 'Iterations/sec', 'Memory (MB)', 'Error']
27
-
28
- # DOM parsing results
29
- add_category_to_csv(csv_data, 'DOM Parsing', @results[:dom_parsing])
30
-
31
- # SAX parsing results
32
- add_category_to_csv(csv_data, 'SAX Parsing', @results[:sax_parsing])
33
-
34
- # XML generation results
35
- add_category_to_csv(csv_data, 'XML Generation', @results[:xml_generation])
36
-
37
- CSV.generate do |csv|
38
- csv_data.each { |row| csv << row }
39
- end
40
- end
41
-
42
- def save_to_files(output_dir = 'results/data')
43
- FileUtils.mkdir_p(output_dir)
44
-
45
- # Save JSON
46
- json_file = File.join(output_dir, 'results.json')
47
- File.write(json_file, to_json)
48
-
49
- # Save CSV
50
- csv_file = File.join(output_dir, 'results.csv')
51
- File.write(csv_file, to_csv)
52
-
53
- {
54
- json: json_file,
55
- csv: csv_file
56
- }
57
- end
58
-
59
- def summary
60
- return 'No results available' unless @results
61
-
62
- summary_lines = []
63
- summary_lines << 'XML Benchmarks Summary'
64
- summary_lines << '=' * 50
65
-
66
- if @results[:environment]
67
- summary_lines << "Environment: Ruby #{@results[:environment][:ruby_version]} on #{@results[:environment][:ruby_platform]}"
68
- summary_lines << "Timestamp: #{@results[:environment][:timestamp]}"
69
- summary_lines << ''
70
- end
71
-
72
- # DOM parsing summary
73
- if @results[:dom_parsing] && !@results[:dom_parsing].empty?
74
- summary_lines << 'DOM Parsing Performance:'
75
- add_category_summary(summary_lines, @results[:dom_parsing])
76
- summary_lines << ''
77
- end
78
-
79
- # SAX parsing summary
80
- if @results[:sax_parsing] && !@results[:sax_parsing].empty?
81
- summary_lines << 'SAX Parsing Performance:'
82
- add_category_summary(summary_lines, @results[:sax_parsing])
83
- summary_lines << ''
84
- end
85
-
86
- # XML generation summary
87
- if @results[:xml_generation] && !@results[:xml_generation].empty?
88
- summary_lines << 'XML Generation Performance:'
89
- add_category_summary(summary_lines, @results[:xml_generation])
90
- summary_lines << ''
91
- end
92
-
93
- # Memory usage summary
94
- if @results[:memory_usage] && !@results[:memory_usage].empty?
95
- summary_lines << 'Memory Usage:'
96
- add_memory_summary(summary_lines, @results[:memory_usage])
97
- end
98
-
99
- summary_lines.join("\n")
100
- end
101
-
102
- private
103
-
104
- def add_category_to_csv(csv_data, category, results)
105
- return unless results
106
-
107
- results.each do |size, parsers|
108
- parsers.each do |parser, data|
109
- memory_mb = if @results[:memory_usage] && @results[:memory_usage][size] && @results[:memory_usage][size][parser]
110
- (@results[:memory_usage][size][parser][:allocated_memory] / 1024.0 / 1024.0).round(2)
111
- else
112
- nil
113
- end
114
-
115
- csv_data << [
116
- category,
117
- size.to_s.capitalize,
118
- parser.capitalize,
119
- data[:error] ? nil : (data[:time_per_iteration] * 1000).round(2),
120
- data[:error] ? nil : data[:iterations_per_second].round(2),
121
- memory_mb,
122
- data[:error] || nil
123
- ]
124
- end
125
- end
126
- end
127
-
128
- def add_category_summary(summary_lines, results)
129
- results.each do |size, parsers|
130
- summary_lines << " #{size.to_s.capitalize} files:"
131
-
132
- # Sort parsers by performance (fastest first)
133
- sorted_parsers = parsers.reject { |_, data| data[:error] }
134
- .sort_by { |_, data| data[:time_per_iteration] }
135
-
136
- sorted_parsers.each_with_index do |(parser, data), index|
137
- time_ms = (data[:time_per_iteration] * 1000).round(2)
138
- rank = case index
139
- when 0 then '🥇'
140
- when 1 then '🥈'
141
- when 2 then '🥉'
142
- else ' '
143
- end
144
- summary_lines << " #{rank} #{parser.capitalize}: #{time_ms}ms"
145
- end
146
-
147
- # Show errors if any
148
- errors = parsers.select { |_, data| data[:error] }
149
- errors.each do |parser, data|
150
- summary_lines << " ❌ #{parser.capitalize}: #{data[:error]}"
151
- end
152
- end
153
- end
154
-
155
- def add_memory_summary(summary_lines, results)
156
- results.each do |size, parsers|
157
- summary_lines << " #{size.to_s.capitalize} files:"
158
-
159
- # Sort parsers by memory usage (lowest first)
160
- sorted_parsers = parsers.reject { |_, data| data[:error] }
161
- .sort_by { |_, data| data[:allocated_memory] }
162
-
163
- sorted_parsers.each_with_index do |(parser, data), index|
164
- memory_mb = (data[:allocated_memory] / 1024.0 / 1024.0).round(2)
165
- rank = case index
166
- when 0 then '🥇'
167
- when 1 then '🥈'
168
- when 2 then '🥉'
169
- else ' '
170
- end
171
- summary_lines << " #{rank} #{parser.capitalize}: #{memory_mb}MB"
172
- end
173
-
174
- # Show errors if any
175
- errors = parsers.select { |_, data| data[:error] }
176
- errors.each do |parser, data|
177
- summary_lines << " ❌ #{parser.capitalize}: #{data[:error]}"
178
- end
179
- end
180
- end
181
- end
182
- end