serialbench 0.1.1 → 0.1.3
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/benchmark.yml +273 -220
- data/.github/workflows/rake.yml +26 -0
- data/.github/workflows/windows-debug.yml +171 -0
- data/.gitignore +32 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +274 -0
- data/Gemfile +14 -1
- data/README.adoc +292 -1118
- data/Rakefile +0 -55
- data/config/benchmarks/full.yml +29 -0
- data/config/benchmarks/short.yml +26 -0
- data/config/environments/asdf-ruby-3.2.yml +8 -0
- data/config/environments/asdf-ruby-3.3.yml +8 -0
- data/config/environments/docker-ruby-3.0.yml +9 -0
- data/config/environments/docker-ruby-3.1.yml +9 -0
- data/config/environments/docker-ruby-3.2.yml +9 -0
- data/config/environments/docker-ruby-3.3.yml +9 -0
- data/config/environments/docker-ruby-3.4.yml +9 -0
- data/data/schemas/result.yml +29 -0
- data/docker/Dockerfile.alpine +33 -0
- data/docker/{Dockerfile.benchmark → Dockerfile.ubuntu} +4 -3
- data/docker/README.md +2 -2
- data/docs/PLATFORM_VALIDATION_FIX.md +79 -0
- data/docs/SYCK_YAML_FIX.md +91 -0
- data/docs/WEBSITE_COMPLETION_PLAN.md +440 -0
- data/docs/WINDOWS_LIBXML_FIX.md +136 -0
- data/docs/WINDOWS_SETUP.md +122 -0
- data/exe/serialbench +1 -1
- data/lib/serialbench/benchmark_runner.rb +261 -423
- data/lib/serialbench/cli/base_cli.rb +51 -0
- data/lib/serialbench/cli/benchmark_cli.rb +453 -0
- data/lib/serialbench/cli/environment_cli.rb +181 -0
- data/lib/serialbench/cli/resultset_cli.rb +261 -0
- data/lib/serialbench/cli/ruby_build_cli.rb +225 -0
- data/lib/serialbench/cli/validate_cli.rb +88 -0
- data/lib/serialbench/cli.rb +61 -600
- data/lib/serialbench/config_manager.rb +129 -0
- data/lib/serialbench/models/benchmark_config.rb +75 -0
- data/lib/serialbench/models/benchmark_result.rb +81 -0
- data/lib/serialbench/models/environment_config.rb +72 -0
- data/lib/serialbench/models/platform.rb +111 -0
- data/lib/serialbench/models/result.rb +80 -0
- data/lib/serialbench/models/result_set.rb +79 -0
- data/lib/serialbench/models/result_store.rb +108 -0
- data/lib/serialbench/models.rb +54 -0
- data/lib/serialbench/ruby_build_manager.rb +149 -0
- data/lib/serialbench/runners/asdf_runner.rb +296 -0
- data/lib/serialbench/runners/base.rb +32 -0
- data/lib/serialbench/runners/docker_runner.rb +140 -0
- data/lib/serialbench/runners/local_runner.rb +71 -0
- data/lib/serialbench/serializers/base_serializer.rb +9 -17
- data/lib/serialbench/serializers/json/base_json_serializer.rb +4 -4
- data/lib/serialbench/serializers/json/json_serializer.rb +0 -2
- data/lib/serialbench/serializers/json/oj_serializer.rb +0 -2
- data/lib/serialbench/serializers/json/rapidjson_serializer.rb +1 -1
- data/lib/serialbench/serializers/json/yajl_serializer.rb +0 -2
- data/lib/serialbench/serializers/toml/base_toml_serializer.rb +5 -5
- data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +1 -3
- data/lib/serialbench/serializers/toml/tomlib_serializer.rb +1 -3
- data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +56 -0
- data/lib/serialbench/serializers/xml/base_xml_serializer.rb +4 -9
- data/lib/serialbench/serializers/xml/libxml_serializer.rb +4 -10
- data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +2 -4
- data/lib/serialbench/serializers/xml/oga_serializer.rb +4 -10
- data/lib/serialbench/serializers/xml/ox_serializer.rb +2 -4
- data/lib/serialbench/serializers/xml/rexml_serializer.rb +3 -5
- data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +5 -1
- data/lib/serialbench/serializers/yaml/psych_serializer.rb +1 -1
- data/lib/serialbench/serializers/yaml/syck_serializer.rb +60 -23
- data/lib/serialbench/serializers.rb +23 -6
- data/lib/serialbench/site_generator.rb +283 -0
- data/lib/serialbench/templates/assets/css/benchmark_report.css +535 -0
- data/lib/serialbench/templates/assets/css/format_based.css +474 -0
- data/lib/serialbench/templates/assets/css/themes.css +589 -0
- data/lib/serialbench/templates/assets/js/chart_helpers.js +411 -0
- data/lib/serialbench/templates/assets/js/dashboard.js +795 -0
- data/lib/serialbench/templates/assets/js/navigation.js +142 -0
- data/lib/serialbench/templates/base.liquid +49 -0
- data/lib/serialbench/templates/format_based.liquid +507 -0
- data/lib/serialbench/templates/partials/chart_section.liquid +4 -0
- data/lib/serialbench/version.rb +1 -1
- data/lib/serialbench/yaml_validator.rb +36 -0
- data/lib/serialbench.rb +2 -31
- data/serialbench.gemspec +15 -3
- metadata +106 -25
- data/.github/workflows/ci.yml +0 -74
- data/.github/workflows/docker.yml +0 -246
- data/config/ci.yml +0 -22
- data/config/full.yml +0 -30
- data/docker/run-benchmarks.sh +0 -356
- data/lib/serialbench/chart_generator.rb +0 -821
- data/lib/serialbench/result_formatter.rb +0 -182
- data/lib/serialbench/result_merger.rb +0 -1201
- data/lib/serialbench/serializers/xml/base_parser.rb +0 -69
- data/lib/serialbench/serializers/xml/libxml_parser.rb +0 -98
- data/lib/serialbench/serializers/xml/nokogiri_parser.rb +0 -111
- data/lib/serialbench/serializers/xml/oga_parser.rb +0 -85
- data/lib/serialbench/serializers/xml/ox_parser.rb +0 -64
- data/lib/serialbench/serializers/xml/rexml_parser.rb +0 -129
data/README.adoc
CHANGED
|
@@ -13,7 +13,7 @@ Serialbench is a comprehensive benchmarking suite that evaluates the performance
|
|
|
13
13
|
|
|
14
14
|
**Key Metrics**: Parsing speed, generation speed, memory usage, streaming capabilities, and feature completeness
|
|
15
15
|
|
|
16
|
-
**
|
|
16
|
+
**Multi-Environment Support**: Docker and ASDF-based multi-Ruby version benchmarking with automated result aggregation and HTML site generation
|
|
17
17
|
|
|
18
18
|
== Supported serialization libraries
|
|
19
19
|
|
|
@@ -80,1121 +80,402 @@ Serialbench is a comprehensive benchmarking suite that evaluates the performance
|
|
|
80
80
|
| https://github.com/emancu/toml-rb[TOML-RB]
|
|
81
81
|
| v2.2.0
|
|
82
82
|
| Pure Ruby TOML parser
|
|
83
|
-
|===
|
|
84
|
-
|
|
85
|
-
== Benchmark report JSON format
|
|
86
|
-
|
|
87
|
-
=== Single Ruby version results
|
|
88
|
-
|
|
89
|
-
The benchmark results are saved as JSON files with the following structure:
|
|
90
|
-
|
|
91
|
-
[source,json]
|
|
92
|
-
----
|
|
93
|
-
{
|
|
94
|
-
"environment": {
|
|
95
|
-
"ruby_version": "3.3.8",
|
|
96
|
-
"ruby_platform": "aarch64-linux",
|
|
97
|
-
"serializer_versions": {
|
|
98
|
-
"rexml": "3.4.1",
|
|
99
|
-
"ox": "2.14.23",
|
|
100
|
-
"nokogiri": "1.18.8",
|
|
101
|
-
"oga": "3.4",
|
|
102
|
-
"libxml": "4.1.2",
|
|
103
|
-
"json": "2.12.2",
|
|
104
|
-
"oj": "3.16.11",
|
|
105
|
-
"yajl": "1.4.3",
|
|
106
|
-
"psych": "5.1.2",
|
|
107
|
-
"syck": "1.5.1.1",
|
|
108
|
-
"toml-rb": "2.2.0",
|
|
109
|
-
"tomlib": "0.7.3"
|
|
110
|
-
},
|
|
111
|
-
"timestamp": "2025-06-07T09:00:25+00:00"
|
|
112
|
-
},
|
|
113
|
-
"parsing": {
|
|
114
|
-
"small": {
|
|
115
|
-
"xml": {
|
|
116
|
-
"rexml": {
|
|
117
|
-
"time_per_iterations": 0.002514416000053643,
|
|
118
|
-
"time_per_iteration": 0.00012572080000268216,
|
|
119
|
-
"iterations_per_second": 7954.133285650949,
|
|
120
|
-
"iterations_count": 20
|
|
121
|
-
},
|
|
122
|
-
"ox": {
|
|
123
|
-
"time_per_iterations": 0.00005258399994545471,
|
|
124
|
-
"time_per_iteration": 0.0000026291999972727353,
|
|
125
|
-
"iterations_per_second": 380343.83121759404,
|
|
126
|
-
"iterations_count": 20
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
"json": {
|
|
130
|
-
"json": {
|
|
131
|
-
"time_per_iterations": 0.000029707999942729657,
|
|
132
|
-
"time_per_iteration": 0.000001485399997136483,
|
|
133
|
-
"iterations_per_second": 673219.3361571126,
|
|
134
|
-
"iterations_count": 20
|
|
135
|
-
},
|
|
136
|
-
"oj": {
|
|
137
|
-
"time_per_iterations": 0.00003158300000905001,
|
|
138
|
-
"time_per_iteration": 0.0000015791500004525006,
|
|
139
|
-
"iterations_per_second": 633252.0658034089,
|
|
140
|
-
"iterations_count": 20
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
"medium": {
|
|
145
|
-
"xml": { /* ... */ },
|
|
146
|
-
"json": { /* ... */ }
|
|
147
|
-
},
|
|
148
|
-
"large": {
|
|
149
|
-
"xml": { /* ... */ },
|
|
150
|
-
"json": { /* ... */ }
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
"ruby_version": "3.3.8",
|
|
154
|
-
"ruby_platform": "aarch64-linux",
|
|
155
|
-
"timestamp": "2025-06-07T09:01:02+00:00"
|
|
156
|
-
}
|
|
157
|
-
----
|
|
158
|
-
|
|
159
|
-
=== Multi-Ruby version merged results
|
|
160
|
-
|
|
161
|
-
When results from multiple Ruby versions are merged, the structure becomes:
|
|
162
|
-
|
|
163
|
-
[source,json]
|
|
164
|
-
----
|
|
165
|
-
{
|
|
166
|
-
"environments": {
|
|
167
|
-
"3_3_8_aarch64_linux": {
|
|
168
|
-
"ruby_version": "3.3.8",
|
|
169
|
-
"ruby_platform": "aarch64-linux",
|
|
170
|
-
"source_file": "docker-results/ruby-3.3/data/results.json",
|
|
171
|
-
"timestamp": "2025-06-07T09:01:02+00:00",
|
|
172
|
-
"environment": {
|
|
173
|
-
"ruby_version": "3.3.8",
|
|
174
|
-
"ruby_platform": "aarch64-linux",
|
|
175
|
-
"serializer_versions": { /* ... */ },
|
|
176
|
-
"timestamp": "2025-06-07T09:00:25+00:00"
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
"3_4_4_aarch64_linux": {
|
|
180
|
-
"ruby_version": "3.4.4",
|
|
181
|
-
"ruby_platform": "aarch64-linux",
|
|
182
|
-
/* ... */
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
"combined_results": {
|
|
186
|
-
"parsing": {
|
|
187
|
-
"small": {
|
|
188
|
-
"xml": {
|
|
189
|
-
"rexml": {
|
|
190
|
-
"3_3_8_aarch64_linux": {
|
|
191
|
-
"time_per_iterations": 0.002514416000053643,
|
|
192
|
-
"time_per_iteration": 0.00012572080000268216,
|
|
193
|
-
"iterations_per_second": 7954.133285650949,
|
|
194
|
-
"iterations_count": 20
|
|
195
|
-
},
|
|
196
|
-
"3_4_4_aarch64_linux": {
|
|
197
|
-
"time_per_iterations": 0.0025308329999234047,
|
|
198
|
-
"time_per_iteration": 0.00012654164999617023,
|
|
199
|
-
"iterations_per_second": 7902.536437846866,
|
|
200
|
-
"iterations_count": 20
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
"metadata": {
|
|
208
|
-
"merged_at": "2025-06-07T17:01:48+08:00",
|
|
209
|
-
"ruby_versions": ["3.3.8", "3.4.4"],
|
|
210
|
-
"platforms": ["aarch64-linux"]
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
----
|
|
214
|
-
|
|
215
|
-
=== JSON schema specification
|
|
216
|
-
|
|
217
|
-
The benchmark results follow this schema:
|
|
218
|
-
|
|
219
|
-
[source,json]
|
|
220
|
-
----
|
|
221
|
-
{
|
|
222
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
223
|
-
"title": "Serialbench Results",
|
|
224
|
-
"type": "object",
|
|
225
|
-
"properties": {
|
|
226
|
-
"environment": {
|
|
227
|
-
"type": "object",
|
|
228
|
-
"properties": {
|
|
229
|
-
"ruby_version": { "type": "string" },
|
|
230
|
-
"ruby_platform": { "type": "string" },
|
|
231
|
-
"serializer_versions": {
|
|
232
|
-
"type": "object",
|
|
233
|
-
"additionalProperties": { "type": "string" }
|
|
234
|
-
},
|
|
235
|
-
"timestamp": { "type": "string", "format": "date-time" }
|
|
236
|
-
},
|
|
237
|
-
"required": ["ruby_version", "ruby_platform", "serializer_versions", "timestamp"]
|
|
238
|
-
},
|
|
239
|
-
"parsing": {
|
|
240
|
-
"type": "object",
|
|
241
|
-
"properties": {
|
|
242
|
-
"small": { "$ref": "#/definitions/sizeResults" },
|
|
243
|
-
"medium": { "$ref": "#/definitions/sizeResults" },
|
|
244
|
-
"large": { "$ref": "#/definitions/sizeResults" }
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
"ruby_version": { "type": "string" },
|
|
248
|
-
"ruby_platform": { "type": "string" },
|
|
249
|
-
"timestamp": { "type": "string", "format": "date-time" }
|
|
250
|
-
},
|
|
251
|
-
"definitions": {
|
|
252
|
-
"sizeResults": {
|
|
253
|
-
"type": "object",
|
|
254
|
-
"properties": {
|
|
255
|
-
"xml": { "$ref": "#/definitions/formatResults" },
|
|
256
|
-
"json": { "$ref": "#/definitions/formatResults" },
|
|
257
|
-
"yaml": { "$ref": "#/definitions/formatResults" },
|
|
258
|
-
"toml": { "$ref": "#/definitions/formatResults" }
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
"formatResults": {
|
|
262
|
-
"type": "object",
|
|
263
|
-
"additionalProperties": {
|
|
264
|
-
"$ref": "#/definitions/serializerResults"
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
"serializerResults": {
|
|
268
|
-
"type": "object",
|
|
269
|
-
"properties": {
|
|
270
|
-
"time_per_iterations": { "type": "number" },
|
|
271
|
-
"time_per_iteration": { "type": "number" },
|
|
272
|
-
"iterations_per_second": { "type": "number" },
|
|
273
|
-
"iterations_count": { "type": "integer" }
|
|
274
|
-
},
|
|
275
|
-
"required": ["time_per_iterations", "time_per_iteration", "iterations_per_second", "iterations_count"]
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
----
|
|
280
|
-
|
|
281
|
-
== Installation
|
|
282
|
-
|
|
283
|
-
Add this line to your application's Gemfile:
|
|
284
|
-
|
|
285
|
-
[source,ruby]
|
|
286
|
-
----
|
|
287
|
-
gem 'serialbench'
|
|
288
|
-
----
|
|
289
|
-
|
|
290
|
-
And then execute:
|
|
291
|
-
|
|
292
|
-
[source]
|
|
293
|
-
----
|
|
294
|
-
$ bundle install
|
|
295
|
-
----
|
|
296
|
-
|
|
297
|
-
Or install it yourself as:
|
|
298
|
-
|
|
299
|
-
[source]
|
|
300
|
-
----
|
|
301
|
-
$ gem install serialbench
|
|
302
|
-
----
|
|
303
|
-
|
|
304
|
-
=== XML library dependencies
|
|
305
|
-
|
|
306
|
-
To run benchmarks for all supported XML libraries, install the following gems:
|
|
307
83
|
|
|
84
|
+
| TOML
|
|
85
|
+
| https://github.com/fbernier/tomlrb[tomlrb]
|
|
86
|
+
| v2.0.3
|
|
87
|
+
| A Racc based TOML Ruby parser (Only supports parsing, no support for dumping/writing.)
|
|
308
88
|
|
|
309
|
-
|
|
310
|
-
----
|
|
311
|
-
# Core XML libraries
|
|
312
|
-
$ gem install ox nokogiri libxml-ruby oga
|
|
89
|
+
|===
|
|
313
90
|
|
|
314
|
-
# Additional format libraries (for comparison)
|
|
315
|
-
$ gem install oj toml-rb
|
|
316
91
|
|
|
317
|
-
|
|
318
|
-
$ gem install memory_profiler
|
|
319
|
-
----
|
|
92
|
+
== Data formats and schema
|
|
320
93
|
|
|
94
|
+
Serialbench generates structured YAML output for benchmark results, with
|
|
95
|
+
different formats for single-environment and multi-environment runs.
|
|
321
96
|
|
|
322
|
-
|
|
97
|
+
The data formats include:
|
|
323
98
|
|
|
324
|
-
|
|
99
|
+
* **Single benchmark results**: Individual benchmark run output
|
|
100
|
+
* **Result set data structure**: Multi-platform benchmark aggregation
|
|
101
|
+
* **JSON schema specification**: Complete schema validation rules
|
|
102
|
+
* **Configuration file formats**: Docker and ASDF configuration examples
|
|
325
103
|
|
|
326
|
-
|
|
104
|
+
== Prerequisites
|
|
327
105
|
|
|
328
|
-
|
|
106
|
+
=== System requirements
|
|
329
107
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
----
|
|
108
|
+
* **Ruby**: 3.0 or later (3.3+ recommended for best performance)
|
|
109
|
+
* **Operating system**: Linux, macOS, or Windows
|
|
110
|
+
* **Architecture**: x86_64 or ARM64
|
|
334
111
|
|
|
335
|
-
|
|
112
|
+
=== Library dependencies
|
|
336
113
|
|
|
337
|
-
|
|
114
|
+
**System dependencies** (required for some native extensions):
|
|
338
115
|
|
|
339
|
-
[source]
|
|
116
|
+
[source,bash]
|
|
340
117
|
----
|
|
341
118
|
# macOS with Homebrew
|
|
342
119
|
$ brew install libxml2 libxslt
|
|
343
|
-
$ gem install nokogiri
|
|
344
|
-
|
|
345
|
-
# Ubuntu/Debian
|
|
346
|
-
$ sudo apt-get install libxml2-dev libxslt1-dev
|
|
347
|
-
$ gem install nokogiri
|
|
348
|
-
----
|
|
349
|
-
|
|
350
|
-
==== LibXML
|
|
351
|
-
|
|
352
|
-
Ruby bindings for libxml2:
|
|
353
|
-
|
|
354
|
-
[source]
|
|
355
|
-
----
|
|
356
|
-
# macOS with Homebrew
|
|
357
|
-
$ brew install libxml2
|
|
358
|
-
$ gem install libxml-ruby
|
|
359
120
|
|
|
360
121
|
# Ubuntu/Debian
|
|
361
|
-
$ sudo apt-get install libxml2-dev
|
|
362
|
-
$ gem install libxml-ruby
|
|
363
|
-
----
|
|
364
|
-
|
|
365
|
-
==== Oga
|
|
366
|
-
|
|
367
|
-
Pure Ruby implementation with no system dependencies:
|
|
122
|
+
$ sudo apt-get install libxml2-dev libxslt1-dev build-essential
|
|
368
123
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
$ gem install oga
|
|
124
|
+
# CentOS/RHEL/Fedora
|
|
125
|
+
$ sudo yum install libxml2-devel libxslt-devel gcc gcc-c++
|
|
372
126
|
----
|
|
373
127
|
|
|
374
|
-
|
|
128
|
+
=== GitHub API token (optional but recommended)
|
|
375
129
|
|
|
376
|
-
Serialbench
|
|
130
|
+
Serialbench fetches Ruby build definitions from the GitHub API. While this works
|
|
131
|
+
without authentication, GitHub imposes strict rate limits on unauthenticated
|
|
132
|
+
requests (60 requests per hour). For better reliability, especially in CI/CD
|
|
133
|
+
environments or when running multiple benchmarks, set the `GITHUB_TOKEN`
|
|
134
|
+
environment variable.
|
|
377
135
|
|
|
378
|
-
|
|
136
|
+
**Rate limits:**
|
|
379
137
|
|
|
380
|
-
|
|
138
|
+
* **Without token**: 60 requests per hour
|
|
139
|
+
* **With token**: 1,000 requests per hour
|
|
381
140
|
|
|
382
|
-
**
|
|
383
|
-
|
|
384
|
-
**Available tags**:
|
|
385
|
-
* `ghcr.io/metanorma/serialbench:main-ruby-3.1` - Ruby 3.1 (linux/amd64, linux/arm64)
|
|
386
|
-
* `ghcr.io/metanorma/serialbench:main-ruby-3.2` - Ruby 3.2 (linux/amd64, linux/arm64)
|
|
387
|
-
* `ghcr.io/metanorma/serialbench:main-ruby-3.3` - Ruby 3.3 (linux/amd64, linux/arm64)
|
|
388
|
-
* `ghcr.io/metanorma/serialbench:main-ruby-3.4` - Ruby 3.4 (linux/amd64, linux/arm64)
|
|
389
|
-
|
|
390
|
-
**Container features**:
|
|
391
|
-
* All serialization libraries pre-installed (XML, JSON, YAML, TOML)
|
|
392
|
-
* Multi-architecture support (Intel x64 and ARM64)
|
|
393
|
-
* Optimized for CI/CD and local development
|
|
394
|
-
* Automatic updates on code changes
|
|
395
|
-
|
|
396
|
-
=== Running benchmarks on your computer
|
|
397
|
-
|
|
398
|
-
==== Windows (PowerShell/Command Prompt)
|
|
399
|
-
|
|
400
|
-
[source,powershell]
|
|
401
|
-
----
|
|
402
|
-
# Pull and run latest Ruby 3.3 container
|
|
403
|
-
docker pull ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
404
|
-
|
|
405
|
-
# Create results directory
|
|
406
|
-
mkdir results
|
|
407
|
-
|
|
408
|
-
# Run benchmarks with volume mounting
|
|
409
|
-
docker run --rm -v ${PWD}/results:/app/results ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
410
|
-
|
|
411
|
-
# View results
|
|
412
|
-
dir results
|
|
413
|
-
----
|
|
414
|
-
|
|
415
|
-
==== macOS (Terminal)
|
|
141
|
+
**Setting the token:**
|
|
416
142
|
|
|
417
143
|
[source,bash]
|
|
418
144
|
----
|
|
419
|
-
#
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
# Create results directory
|
|
423
|
-
mkdir -p results
|
|
424
|
-
|
|
425
|
-
# Run benchmarks with volume mounting
|
|
426
|
-
docker run --rm -v $(pwd)/results:/app/results ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
427
|
-
|
|
428
|
-
# View results
|
|
429
|
-
ls -la results/
|
|
430
|
-
----
|
|
431
|
-
|
|
432
|
-
==== Ubuntu/Linux (Terminal)
|
|
433
|
-
|
|
434
|
-
[source,bash]
|
|
435
|
-
----
|
|
436
|
-
# Pull and run latest Ruby 3.3 container
|
|
437
|
-
docker pull ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
438
|
-
|
|
439
|
-
# Create results directory
|
|
440
|
-
mkdir -p results
|
|
441
|
-
|
|
442
|
-
# Run benchmarks with volume mounting
|
|
443
|
-
docker run --rm -v $(pwd)/results:/app/results ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
145
|
+
# For local usage
|
|
146
|
+
export GITHUB_TOKEN=ghp_your_token_here
|
|
444
147
|
|
|
445
|
-
#
|
|
446
|
-
|
|
148
|
+
# For GitHub Actions (automatic)
|
|
149
|
+
# GitHub Actions automatically provides ${{ secrets.GITHUB_TOKEN }}
|
|
150
|
+
# No manual configuration needed in workflows
|
|
447
151
|
----
|
|
448
152
|
|
|
449
|
-
|
|
153
|
+
**Creating a token:**
|
|
450
154
|
|
|
451
|
-
|
|
155
|
+
. Go to https://github.com/settings/tokens
|
|
156
|
+
. Click "Generate new token (classic)"
|
|
157
|
+
. Select scope: `public_repo` (for accessing public repositories)
|
|
158
|
+
. Copy the generated token
|
|
159
|
+
. Store it securely in your environment
|
|
452
160
|
|
|
453
|
-
|
|
161
|
+
NOTE: The token is optional. Serialbench will work without it but may hit rate
|
|
162
|
+
limits when updating Ruby build definitions frequently.
|
|
454
163
|
|
|
455
|
-
|
|
456
|
-
----
|
|
457
|
-
# Create results directories
|
|
458
|
-
$versions = @("3.1", "3.2", "3.3", "3.4")
|
|
459
|
-
foreach ($version in $versions) {
|
|
460
|
-
mkdir "results-ruby-$version" -Force
|
|
461
|
-
docker pull "ghcr.io/metanorma/serialbench:main-ruby-$version"
|
|
462
|
-
docker run --rm -v "${PWD}/results-ruby-${version}:/app/results" "ghcr.io/metanorma/serialbench:main-ruby-$version"
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
# View all results
|
|
466
|
-
dir results-ruby-*
|
|
467
|
-
----
|
|
468
|
-
|
|
469
|
-
==== macOS/Linux (Bash)
|
|
470
|
-
|
|
471
|
-
[source,bash]
|
|
472
|
-
----
|
|
473
|
-
# Run benchmarks for all Ruby versions
|
|
474
|
-
for version in 3.1 3.2 3.3 3.4; do
|
|
475
|
-
echo "Running benchmarks for Ruby $version..."
|
|
476
|
-
mkdir -p "results-ruby-$version"
|
|
477
|
-
docker pull "ghcr.io/metanorma/serialbench:main-ruby-$version"
|
|
478
|
-
docker run --rm \
|
|
479
|
-
-v "$(pwd)/results-ruby-$version:/app/results" \
|
|
480
|
-
"ghcr.io/metanorma/serialbench:main-ruby-$version"
|
|
481
|
-
done
|
|
482
|
-
|
|
483
|
-
# View all results
|
|
484
|
-
ls -la results-ruby-*/
|
|
485
|
-
----
|
|
486
|
-
|
|
487
|
-
=== Custom benchmark configuration
|
|
164
|
+
== Installation
|
|
488
165
|
|
|
489
|
-
|
|
166
|
+
Add this line to your application's Gemfile:
|
|
490
167
|
|
|
491
|
-
[source,
|
|
168
|
+
[source,ruby]
|
|
492
169
|
----
|
|
493
|
-
|
|
494
|
-
docker run --rm \
|
|
495
|
-
-v $(pwd)/results:/app/results \
|
|
496
|
-
ghcr.io/metanorma/serialbench:main-ruby-3.3 \
|
|
497
|
-
bundle exec serialbench benchmark --formats xml json --iterations 10
|
|
498
|
-
|
|
499
|
-
# Run with memory profiling
|
|
500
|
-
docker run --rm \
|
|
501
|
-
-v $(pwd)/results:/app/results \
|
|
502
|
-
ghcr.io/metanorma/serialbench:main-ruby-3.3 \
|
|
503
|
-
bundle exec serialbench benchmark --memory-profiling
|
|
504
|
-
|
|
505
|
-
# List available serializers
|
|
506
|
-
docker run --rm ghcr.io/metanorma/serialbench:main-ruby-3.3 \
|
|
507
|
-
bundle exec serialbench list
|
|
170
|
+
gem 'serialbench'
|
|
508
171
|
----
|
|
509
172
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
==== Prerequisites
|
|
513
|
-
|
|
514
|
-
* Docker installed and running
|
|
515
|
-
* Command line access (PowerShell, Terminal, or Bash)
|
|
516
|
-
|
|
517
|
-
==== Running multi-Ruby benchmarks
|
|
173
|
+
And then execute:
|
|
518
174
|
|
|
519
175
|
[source]
|
|
520
176
|
----
|
|
521
|
-
|
|
522
|
-
$ ./docker/run-benchmarks.sh
|
|
523
|
-
|
|
524
|
-
# Or using published containers directly
|
|
525
|
-
$ docker pull ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
526
|
-
$ docker run --rm -v $(pwd)/results:/app/results ghcr.io/metanorma/serialbench:main-ruby-3.3
|
|
177
|
+
$ bundle install
|
|
527
178
|
----
|
|
528
179
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
. **Pull pre-built containers** from GitHub Container Registry
|
|
532
|
-
. **Run comprehensive benchmarks** in isolated environments
|
|
533
|
-
. **Generate detailed reports** with performance comparisons
|
|
534
|
-
. **Output results** to your local `results/` directory
|
|
535
|
-
|
|
536
|
-
==== Results structure
|
|
537
|
-
|
|
538
|
-
Results are organized in `docker-results/`:
|
|
180
|
+
Or install it yourself as:
|
|
539
181
|
|
|
540
182
|
[source]
|
|
541
183
|
----
|
|
542
|
-
|
|
543
|
-
├── ruby-3.0/ # Ruby 3.0 individual results
|
|
544
|
-
│ ├── benchmark.log # Execution log
|
|
545
|
-
│ ├── data/
|
|
546
|
-
│ │ ├── results.json # Raw benchmark data
|
|
547
|
-
│ │ └── results.yaml # YAML format results
|
|
548
|
-
│ ├── reports/
|
|
549
|
-
│ │ └── benchmark_report.html
|
|
550
|
-
│ └── assets/
|
|
551
|
-
├── ruby-3.1/ # Ruby 3.1 individual results
|
|
552
|
-
├── ruby-3.2/ # Ruby 3.2 individual results
|
|
553
|
-
├── ruby-3.3/ # Ruby 3.3 individual results
|
|
554
|
-
├── ruby-3.4/ # Ruby 3.4 individual results
|
|
555
|
-
├── merged/ # Aggregated cross-version results
|
|
556
|
-
│ └── merged_results.json # Combined performance data
|
|
557
|
-
└── docs/ # GitHub Pages ready output
|
|
558
|
-
├── index.html # Interactive comparison report
|
|
559
|
-
├── styles.css # Report styling
|
|
560
|
-
└── merged_results.json # Data for interactive charts
|
|
184
|
+
$ gem install serialbench
|
|
561
185
|
----
|
|
562
186
|
|
|
563
|
-
=== Manual Docker usage
|
|
564
187
|
|
|
565
|
-
|
|
188
|
+
== Command line interface
|
|
566
189
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
$ docker build \
|
|
570
|
-
--build-arg RUBY_VERSION=3.3 \
|
|
571
|
-
-t serialbench:ruby-3.3 \
|
|
572
|
-
-f docker/Dockerfile.benchmark \
|
|
573
|
-
.
|
|
574
|
-
----
|
|
190
|
+
Serialbench provides a comprehensive Thor-based CLI with four main subcommands
|
|
191
|
+
for managing environments, benchmarks, result sets, and Ruby builds.
|
|
575
192
|
|
|
576
|
-
|
|
193
|
+
=== Main Commands Overview
|
|
577
194
|
|
|
578
|
-
[source]
|
|
195
|
+
[source,sh]
|
|
579
196
|
----
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
# Run benchmarks with volume mounting
|
|
584
|
-
$ docker run \
|
|
585
|
-
--rm \
|
|
586
|
-
-v $(pwd)/results:/app/results \
|
|
587
|
-
serialbench:ruby-3.3
|
|
588
|
-
----
|
|
589
|
-
|
|
590
|
-
==== Custom configuration
|
|
197
|
+
$ serialbench
|
|
198
|
+
Serialbench - Benchmarking Framework for Ruby Serialization Libraries
|
|
591
199
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
# Use custom config file
|
|
595
|
-
$ docker run \
|
|
596
|
-
--rm \
|
|
597
|
-
-v $(pwd)/results:/app/results \
|
|
598
|
-
-v $(pwd)/config:/app/config \
|
|
599
|
-
serialbench:ruby-3.3 \
|
|
600
|
-
bundle exec serialbench benchmark --config config/ci.yml
|
|
601
|
-
----
|
|
200
|
+
USAGE:
|
|
201
|
+
serialbench COMMAND [SUBCOMMAND] [OPTIONS]
|
|
602
202
|
|
|
603
|
-
|
|
203
|
+
COMMANDS:
|
|
204
|
+
environment Manage benchmark environments (Docker, ASDF, Local)
|
|
205
|
+
benchmark Manage individual benchmark runs
|
|
206
|
+
resultset Manage benchmark resultsets (collections of runs)
|
|
207
|
+
ruby-build Manage Ruby-Build definitions for validation
|
|
208
|
+
version Show version information
|
|
209
|
+
help Show this help message
|
|
604
210
|
|
|
605
|
-
|
|
211
|
+
EXAMPLES:
|
|
212
|
+
# Create a Docker environment
|
|
213
|
+
serialbench environment new docker-test docker
|
|
606
214
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
* **Ruby 3.3** - Latest stable with performance improvements
|
|
611
|
-
* **Ruby 3.4** - Current development version
|
|
612
|
-
|
|
613
|
-
Each version includes all supported serialization libraries:
|
|
614
|
-
|
|
615
|
-
* **XML**: REXML (built-in), Ox, Nokogiri, Oga, LibXML
|
|
616
|
-
* **JSON**: JSON (built-in), Oj, YAJL
|
|
617
|
-
* **YAML**: Psych (built-in), Syck
|
|
618
|
-
* **TOML**: TOML-RB, Tomlib
|
|
619
|
-
|
|
620
|
-
=== Environment variables
|
|
621
|
-
|
|
622
|
-
The Docker images support these environment variables:
|
|
623
|
-
|
|
624
|
-
* `BUNDLE_PATH` - Bundle installation path
|
|
625
|
-
* `BUNDLE_BIN` - Bundle binary path
|
|
626
|
-
* `PATH` - System PATH including bundle binaries
|
|
627
|
-
* `RUBY_VERSION` - Ruby version for build-time configuration
|
|
628
|
-
|
|
629
|
-
=== Result aggregation and GitHub Pages
|
|
630
|
-
|
|
631
|
-
==== Merging multi-version results
|
|
632
|
-
|
|
633
|
-
The Docker workflow automatically merges results from all Ruby versions:
|
|
634
|
-
|
|
635
|
-
[source]
|
|
636
|
-
----
|
|
637
|
-
# Manual result merging
|
|
638
|
-
$ serialbench merge_results \
|
|
639
|
-
docker-results/ruby-3.0 \
|
|
640
|
-
docker-results/ruby-3.1 \
|
|
641
|
-
docker-results/ruby-3.2 \
|
|
642
|
-
docker-results/ruby-3.3 \
|
|
643
|
-
docker-results/ruby-3.4 \
|
|
644
|
-
docker-results/merged
|
|
645
|
-
----
|
|
215
|
+
# Run multi-environment benchmarks
|
|
216
|
+
serialbench environment multi-execute asdf --config=serialbench-asdf.yml
|
|
217
|
+
serialbench environment multi-execute docker --config=serialbench-docker.yml
|
|
646
218
|
|
|
647
|
-
|
|
219
|
+
# Create and execute a benchmark
|
|
220
|
+
serialbench benchmark create my-benchmark
|
|
221
|
+
serialbench benchmark execute my-benchmark.yml
|
|
648
222
|
|
|
649
|
-
|
|
223
|
+
# Create a result set for comparison
|
|
224
|
+
serialbench resultset create comparison-set
|
|
225
|
+
serialbench resultset add-result comparison-set results/my-benchmark
|
|
650
226
|
|
|
651
|
-
|
|
227
|
+
# Generate static sites
|
|
228
|
+
serialbench benchmark build-site results/my-benchmark
|
|
229
|
+
serialbench resultset build-site resultsets/comparison-set
|
|
652
230
|
----
|
|
653
|
-
# Generate GitHub Pages from multi-version results
|
|
654
|
-
$ serialbench github_pages \
|
|
655
|
-
docker-results/ruby-3.0 \
|
|
656
|
-
docker-results/ruby-3.1 \
|
|
657
|
-
docker-results/ruby-3.2 \
|
|
658
|
-
docker-results/ruby-3.3 \
|
|
659
|
-
docker-results/ruby-3.4 \
|
|
660
|
-
docker-results/docs
|
|
661
|
-
----
|
|
662
|
-
|
|
663
|
-
The generated GitHub Pages include:
|
|
664
231
|
|
|
665
|
-
|
|
666
|
-
* **Multi-Version Analysis**: See how performance changes between Ruby releases
|
|
667
|
-
* **Environment Details**: Ruby versions, platforms, and library versions
|
|
668
|
-
* **Responsive Design**: Works on desktop and mobile devices
|
|
669
|
-
* **Direct Deployment**: Ready for GitHub Pages, Netlify, or any static hosting
|
|
232
|
+
=== Environment management
|
|
670
233
|
|
|
671
|
-
|
|
234
|
+
The `environment` subcommand manages environment configurations and executes
|
|
235
|
+
benchmarks across different Ruby environments.
|
|
672
236
|
|
|
673
|
-
. **Commit the generated files**:
|
|
674
|
-
+
|
|
675
237
|
[source]
|
|
676
238
|
----
|
|
677
|
-
$
|
|
678
|
-
|
|
679
|
-
|
|
239
|
+
$ serialbench environment help
|
|
240
|
+
Commands:
|
|
241
|
+
serialbench environment execute ENVIRONMENT_CONFIG BENCHMARK_CONFIG RESULT_PATH # Execute benchmark in environment
|
|
242
|
+
serialbench environment help [COMMAND] # Describe subcommands or one specific subcommand
|
|
243
|
+
serialbench environment new NAME KIND RUBY_BUILD_TAG # Create a new environment configuration
|
|
244
|
+
serialbench environment prepare ENVIRONMENT_CONFIG # Prepare environment for benchmarking
|
|
680
245
|
----
|
|
681
246
|
|
|
682
|
-
. **Enable GitHub Pages** in repository settings:
|
|
683
|
-
.. Go to Settings → Pages
|
|
684
|
-
.. Set source to "Deploy from a branch"
|
|
685
|
-
.. Select branch containing the `docs/` folder
|
|
686
|
-
.. Set folder to `/docker-results/docs`
|
|
687
|
-
|
|
688
|
-
. **Access your results** at: `https://yourusername.github.io/yourrepo/`
|
|
689
247
|
|
|
690
|
-
===
|
|
248
|
+
=== Benchmark management
|
|
691
249
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
Check build logs for specific Ruby versions:
|
|
250
|
+
The `benchmark` subcommand handles individual benchmark runs and site generation.
|
|
695
251
|
|
|
696
252
|
[source]
|
|
697
253
|
----
|
|
698
|
-
$
|
|
254
|
+
$ serialbench benchmark help
|
|
255
|
+
Commands:
|
|
256
|
+
serialbench benchmark _docker_execute ENVIRONMENT_CONFIG_PATH BENCHMARK_CONFIG_PATH # (Private) Execute a benchmark run
|
|
257
|
+
serialbench benchmark build-site RUN_PATH [OUTPUT_DIR] # Generate HTML site for a run
|
|
258
|
+
serialbench benchmark create [NAME] # Generate a run configuration file
|
|
259
|
+
serialbench benchmark execute ENVIRONMENT_CONFIG_PATH BENCHMARK_CONFIG_PATH # Execute a benchmark run
|
|
260
|
+
serialbench benchmark help [COMMAND] # Describe subcommands or one specific subcommand
|
|
261
|
+
serialbench benchmark list # List all available runs
|
|
699
262
|
----
|
|
700
263
|
|
|
701
|
-
|
|
264
|
+
The `_docker_execute` command is a private command used internally by the
|
|
265
|
+
`execute` command to run benchmarks in Docker environments.
|
|
702
266
|
|
|
703
|
-
* **Missing system dependencies**: Ensure libxml2-dev and libxslt1-dev are available
|
|
704
|
-
* **Network timeouts**: Retry the build or use a different network
|
|
705
|
-
* **Disk space**: Ensure sufficient disk space for multiple Ruby images
|
|
706
267
|
|
|
707
|
-
|
|
268
|
+
=== Result set management
|
|
708
269
|
|
|
709
|
-
|
|
270
|
+
The `resultset` subcommand manages collections of benchmark runs for comparison analysis.
|
|
710
271
|
|
|
711
272
|
[source]
|
|
712
273
|
----
|
|
713
|
-
$
|
|
274
|
+
$ serialbench resultset help
|
|
275
|
+
Commands:
|
|
276
|
+
serialbench resultset add-result RESULT_PATH RESULTSET_PATH # Add a run to a resultset
|
|
277
|
+
serialbench resultset build-site RESULTSET_PATH [OUTPUT_DIR] # Generate HTML site for a resultset
|
|
278
|
+
serialbench resultset create NAME PATH # Create a new resultset
|
|
279
|
+
serialbench resultset help [COMMAND] # Describe subcommands or one specific subcommand
|
|
280
|
+
serialbench resultset list # List all available resultsets
|
|
281
|
+
serialbench resultset remove-result RESULTSET_PATH RESULT_PATH # Remove a run from a resultset
|
|
714
282
|
----
|
|
715
283
|
|
|
716
|
-
Common runtime issues:
|
|
717
284
|
|
|
718
|
-
|
|
719
|
-
* **Timeout issues**: Some benchmarks may take longer on slower systems
|
|
720
|
-
* **Permission errors**: Ensure proper volume mounting permissions
|
|
285
|
+
=== ruby-build management
|
|
721
286
|
|
|
722
|
-
|
|
287
|
+
The `ruby-build` subcommand manages Ruby build definitions and version information.
|
|
723
288
|
|
|
724
|
-
|
|
289
|
+
Serialbench uses ruby-build definitions of Ruby interpreter types and versions
|
|
290
|
+
for identification.
|
|
725
291
|
|
|
726
292
|
[source]
|
|
727
293
|
----
|
|
728
|
-
$
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
294
|
+
$ serialbench ruby-build help
|
|
295
|
+
Commands:
|
|
296
|
+
serialbench ruby_build cache-info # Show information about the Ruby-Build definitions cache
|
|
297
|
+
serialbench ruby_build help [COMMAND] # Describe subcommands or one specific subcommand
|
|
298
|
+
serialbench ruby_build list [FILTER] # List available Ruby-Build definitions
|
|
299
|
+
serialbench ruby_build show TAG # Show details for a specific Ruby-Build definition
|
|
300
|
+
serialbench ruby_build suggest # Suggest Ruby-Build tag for current Ruby version
|
|
301
|
+
serialbench ruby_build update # Update Ruby-Build definitions from GitHub
|
|
302
|
+
serialbench ruby_build validate TAG # Validate a Ruby-Build tag
|
|
736
303
|
----
|
|
737
|
-
# Remove all Serialbench images
|
|
738
|
-
$ docker rmi $(docker images serialbench -q)
|
|
739
304
|
|
|
740
|
-
# Remove all containers
|
|
741
|
-
$ docker container prune
|
|
742
|
-
----
|
|
743
305
|
|
|
744
|
-
|
|
306
|
+
== Workflow examples
|
|
745
307
|
|
|
746
|
-
|
|
308
|
+
=== Docker-based testing
|
|
747
309
|
|
|
748
|
-
|
|
310
|
+
NOTE: This works.
|
|
749
311
|
|
|
750
312
|
[source,bash]
|
|
751
313
|
----
|
|
752
|
-
|
|
753
|
-
|
|
314
|
+
# 1. Prepare Docker environment
|
|
315
|
+
$ bundle exec serialbench environment prepare config/environments/docker-ruby-3.1.yml
|
|
754
316
|
|
|
755
|
-
|
|
317
|
+
# 2. Run benchmark
|
|
318
|
+
$ bundle exec serialbench environment execute config/environments/docker-ruby-3.1.yml config/benchmarks/short.yml results/runs/docker-ruby-3.1-results
|
|
756
319
|
|
|
757
|
-
|
|
320
|
+
# 3. Create a resultset
|
|
321
|
+
$ bundle exec serialbench resultset create docker-comparison results/sets/docker-comparison
|
|
758
322
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
# config/custom.yml
|
|
762
|
-
formats:
|
|
763
|
-
- xml
|
|
764
|
-
- json
|
|
765
|
-
iterations: 50
|
|
766
|
-
warmup: 5
|
|
767
|
-
data_sizes:
|
|
768
|
-
- small
|
|
769
|
-
- medium
|
|
770
|
-
----
|
|
771
|
-
|
|
772
|
-
Reference the custom config in the run script:
|
|
323
|
+
# 3a. (Optional) Build the site from the result if you want to visualize results
|
|
324
|
+
$ bundle exec serialbench benchmark build-site results/runs/docker-ruby-3.1-results/ --output_dir=_site_result
|
|
773
325
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
# In docker/run-benchmarks.sh
|
|
777
|
-
CONFIG_FILE="config/custom.yml"
|
|
778
|
-
----
|
|
326
|
+
# 4. Add the result to the resultset
|
|
327
|
+
$ bundle exec serialbench resultset add-result results/sets/docker-comparison/ results/runs/docker-ruby-3.1-results/
|
|
779
328
|
|
|
780
|
-
|
|
329
|
+
# 5. Build the site from the resultset
|
|
330
|
+
$ bundle exec serialbench resultset build-site results/sets/docker-comparison/
|
|
781
331
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
[source,bash]
|
|
785
|
-
----
|
|
786
|
-
# In docker/run-benchmarks.sh
|
|
787
|
-
OUTPUT_DIR="my-benchmark-results"
|
|
332
|
+
# 6. Open the generated site
|
|
333
|
+
$ open _site/index.html
|
|
788
334
|
----
|
|
789
335
|
|
|
790
|
-
===
|
|
791
|
-
|
|
792
|
-
==== GitHub Actions integration
|
|
793
|
-
|
|
794
|
-
The Docker setup integrates seamlessly with GitHub Actions:
|
|
795
|
-
|
|
796
|
-
[source,yaml]
|
|
797
|
-
----
|
|
798
|
-
# .github/workflows/benchmark.yml
|
|
799
|
-
name: Multi-Ruby Benchmarks
|
|
800
|
-
|
|
801
|
-
on:
|
|
802
|
-
schedule:
|
|
803
|
-
- cron: '0 2 * * 0' # Weekly on Sunday at 2 AM
|
|
804
|
-
workflow_dispatch:
|
|
805
|
-
|
|
806
|
-
permissions:
|
|
807
|
-
contents: read
|
|
808
|
-
pages: write
|
|
809
|
-
id-token: write
|
|
810
|
-
|
|
811
|
-
concurrency:
|
|
812
|
-
group: "pages"
|
|
813
|
-
cancel-in-progress: false
|
|
814
|
-
|
|
815
|
-
jobs:
|
|
816
|
-
benchmark:
|
|
817
|
-
runs-on: ubuntu-latest
|
|
818
|
-
steps:
|
|
819
|
-
- name: Checkout repository
|
|
820
|
-
uses: actions/checkout@v4
|
|
821
|
-
|
|
822
|
-
- name: Setup Docker Buildx
|
|
823
|
-
uses: docker/setup-buildx-action@v3
|
|
824
|
-
|
|
825
|
-
- name: Run Docker Benchmarks
|
|
826
|
-
run: ./docker/run-benchmarks.sh
|
|
827
|
-
|
|
828
|
-
- name: Upload Results
|
|
829
|
-
uses: actions/upload-artifact@v4
|
|
830
|
-
with:
|
|
831
|
-
name: benchmark-results
|
|
832
|
-
path: docker-results/
|
|
833
|
-
|
|
834
|
-
- name: Setup Pages
|
|
835
|
-
uses: actions/configure-pages@v4
|
|
836
|
-
|
|
837
|
-
- name: Upload Pages artifact
|
|
838
|
-
uses: actions/upload-pages-artifact@v3
|
|
839
|
-
with:
|
|
840
|
-
path: ./docker-results/docs
|
|
841
|
-
|
|
842
|
-
deploy:
|
|
843
|
-
environment:
|
|
844
|
-
name: github-pages
|
|
845
|
-
url: ${{ steps.deployment.outputs.page_url }}
|
|
846
|
-
runs-on: ubuntu-latest
|
|
847
|
-
needs: benchmark
|
|
848
|
-
steps:
|
|
849
|
-
- name: Deploy to GitHub Pages
|
|
850
|
-
id: deployment
|
|
851
|
-
uses: actions/deploy-pages@v4
|
|
852
|
-
----
|
|
853
|
-
|
|
854
|
-
==== Performance considerations
|
|
855
|
-
|
|
856
|
-
* **Parallel builds**: Docker builds can run in parallel for faster execution
|
|
857
|
-
* **Build caching**: Subsequent runs use cached layers for faster builds
|
|
858
|
-
* **Memory profiling**: Enabled by default but can be disabled for faster runs
|
|
859
|
-
* **Result compression**: Large result files can be compressed for storage
|
|
860
|
-
|
|
861
|
-
=== Security considerations
|
|
862
|
-
|
|
863
|
-
* **Containers run with minimal privileges**: No root access required
|
|
864
|
-
* **No network access during benchmarks**: Isolated execution environment
|
|
865
|
-
* **Volume mounting**: Results written only to specified mounted volumes
|
|
866
|
-
* **Image scanning**: Regular security updates for base Ruby images
|
|
867
|
-
|
|
868
|
-
== Usage
|
|
869
|
-
|
|
870
|
-
=== Command line interface
|
|
871
|
-
|
|
872
|
-
==== Basic usage
|
|
873
|
-
|
|
874
|
-
Run benchmarks for all available formats:
|
|
875
|
-
|
|
876
|
-
[source]
|
|
877
|
-
----
|
|
878
|
-
$ serialbench benchmark
|
|
879
|
-
----
|
|
336
|
+
=== ASDF-based testing
|
|
880
337
|
|
|
881
|
-
|
|
338
|
+
WARNING: THIS IS NOT YET WORKING.
|
|
882
339
|
|
|
883
|
-
[source]
|
|
884
|
-
----
|
|
885
|
-
$ serialbench list
|
|
886
|
-
----
|
|
887
|
-
|
|
888
|
-
Show help information:
|
|
889
|
-
|
|
890
|
-
[source]
|
|
891
|
-
----
|
|
892
|
-
$ serialbench help
|
|
893
|
-
$ serialbench help benchmark
|
|
894
|
-
----
|
|
895
|
-
|
|
896
|
-
Show version:
|
|
897
|
-
|
|
898
|
-
[source]
|
|
899
|
-
----
|
|
900
|
-
$ serialbench version
|
|
901
|
-
----
|
|
902
|
-
|
|
903
|
-
==== Format-specific benchmarks
|
|
904
|
-
|
|
905
|
-
===== XML benchmarks
|
|
906
|
-
|
|
907
|
-
Run all XML library benchmarks:
|
|
908
|
-
|
|
909
|
-
[source]
|
|
910
|
-
----
|
|
911
|
-
$ serialbench benchmark --formats xml
|
|
912
|
-
----
|
|
913
|
-
|
|
914
|
-
Test specific XML libraries:
|
|
915
|
-
|
|
916
|
-
[source]
|
|
917
|
-
----
|
|
918
|
-
$ serialbench benchmark --formats xml --parsers ox,nokogiri
|
|
919
|
-
$ serialbench benchmark --formats xml --parsers rexml,oga,libxml
|
|
340
|
+
[source,bash]
|
|
920
341
|
----
|
|
342
|
+
# 1. Validate configuration
|
|
343
|
+
$ bundle exec serialbench benchmark validate serialbench-asdf.yml
|
|
921
344
|
|
|
922
|
-
|
|
345
|
+
# 2. Prepare Ruby environments
|
|
346
|
+
$ bundle exec serialbench benchmark prepare asdf --config=serialbench-asdf.yml
|
|
923
347
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
$ serialbench benchmark --formats xml --parsing-only
|
|
927
|
-
----
|
|
348
|
+
# 3. Run benchmarks across all Ruby versions
|
|
349
|
+
$ bundle exec serialbench benchmark execute asdf --config=serialbench-asdf.yml
|
|
928
350
|
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
[source]
|
|
932
|
-
----
|
|
933
|
-
$ serialbench benchmark --formats xml --generation-only
|
|
351
|
+
# 4. Results are automatically merged and dashboard generated
|
|
352
|
+
$ open asdf-results/_site/index.html
|
|
934
353
|
----
|
|
935
354
|
|
|
936
|
-
XML streaming/SAX parsing:
|
|
937
355
|
|
|
938
|
-
[source]
|
|
939
|
-
----
|
|
940
|
-
$ serialbench benchmark --formats xml --streaming-only
|
|
941
|
-
----
|
|
942
|
-
|
|
943
|
-
===== JSON benchmarks
|
|
944
|
-
|
|
945
|
-
Run all JSON library benchmarks:
|
|
946
|
-
|
|
947
|
-
[source]
|
|
948
|
-
----
|
|
949
|
-
$ serialbench benchmark --formats json
|
|
950
|
-
----
|
|
951
356
|
|
|
952
|
-
Test specific JSON libraries:
|
|
953
357
|
|
|
954
|
-
|
|
955
|
-
----
|
|
956
|
-
$ serialbench benchmark --formats json --parsers oj,json
|
|
957
|
-
$ serialbench benchmark --formats json --parsers yajl,oj
|
|
958
|
-
----
|
|
358
|
+
== Configuration Files
|
|
959
359
|
|
|
960
|
-
|
|
360
|
+
=== Environment configuration
|
|
961
361
|
|
|
962
|
-
|
|
362
|
+
Environment configuration files define how benchmarks are executed in different runtime environments.
|
|
963
363
|
|
|
964
|
-
|
|
364
|
+
.Environment configuration for Docker (`config/environments/docker-ruby-3.4.yml`)
|
|
365
|
+
[source,yaml]
|
|
965
366
|
----
|
|
966
|
-
|
|
367
|
+
---
|
|
368
|
+
name: docker-ruby-3.4
|
|
369
|
+
kind: docker
|
|
370
|
+
created_at: '2025-06-13T15:18:43+08:00'
|
|
371
|
+
ruby_build_tag: "3.4.1"
|
|
372
|
+
description: Docker environment for Ruby 3.4 benchmarks
|
|
373
|
+
docker:
|
|
374
|
+
image: 'ruby:3.4-slim'
|
|
375
|
+
dockerfile: '../../docker/Dockerfile.ubuntu'
|
|
967
376
|
----
|
|
968
377
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
[source]
|
|
378
|
+
.Environment configuration for ASDF (`config/environments/asdf-ruby-3.3.yml`)
|
|
379
|
+
[source,yaml]
|
|
972
380
|
----
|
|
973
|
-
|
|
381
|
+
---
|
|
382
|
+
name: ruby-332-asdf
|
|
383
|
+
kind: asdf
|
|
384
|
+
created_at: '2025-06-12T22:53:24+08:00'
|
|
385
|
+
ruby_build_tag: 3.3.2
|
|
386
|
+
description: ASDF environment
|
|
387
|
+
asdf:
|
|
388
|
+
auto_install: true
|
|
974
389
|
----
|
|
975
390
|
|
|
976
|
-
|
|
391
|
+
=== Benchmark configuration
|
|
977
392
|
|
|
978
|
-
|
|
393
|
+
Benchmark configuration files control what tests to run and how to run them.
|
|
979
394
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
$ serialbench benchmark --formats xml json
|
|
983
|
-
----
|
|
984
|
-
|
|
985
|
-
Compare all supported formats:
|
|
986
|
-
|
|
987
|
-
[source]
|
|
988
|
-
----
|
|
989
|
-
$ serialbench benchmark --formats xml json toml
|
|
395
|
+
.Short configuration (CI-friendly) (`config/benchmarks/short.yml`)
|
|
396
|
+
[source,yaml]
|
|
990
397
|
----
|
|
398
|
+
name: short-benchmark
|
|
991
399
|
|
|
992
|
-
|
|
400
|
+
data_sizes:
|
|
401
|
+
- small
|
|
993
402
|
|
|
994
|
-
|
|
403
|
+
formats:
|
|
404
|
+
- xml
|
|
405
|
+
- json
|
|
406
|
+
- yaml
|
|
407
|
+
- toml
|
|
995
408
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
409
|
+
iterations:
|
|
410
|
+
small: 5
|
|
411
|
+
medium: 2
|
|
412
|
+
large: 1
|
|
1000
413
|
|
|
1001
|
-
|
|
414
|
+
operations:
|
|
415
|
+
- parse
|
|
416
|
+
- generate
|
|
417
|
+
- streaming
|
|
1002
418
|
|
|
1003
|
-
|
|
1004
|
-
----
|
|
1005
|
-
$ serialbench benchmark --detailed-reports
|
|
419
|
+
warmup: 2
|
|
1006
420
|
----
|
|
1007
421
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
[source]
|
|
1011
|
-
----
|
|
1012
|
-
$ serialbench benchmark --output-format json
|
|
422
|
+
.Full configuration (Comprehensive) (`config/benchmarks/full.yml`)
|
|
423
|
+
[source,yaml]
|
|
1013
424
|
----
|
|
425
|
+
name: full-benchmark
|
|
1014
426
|
|
|
1015
|
-
|
|
427
|
+
data_sizes:
|
|
428
|
+
- small
|
|
429
|
+
- medium
|
|
430
|
+
- large
|
|
1016
431
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
432
|
+
formats:
|
|
433
|
+
- xml
|
|
434
|
+
- json
|
|
435
|
+
- yaml
|
|
436
|
+
- toml
|
|
1021
437
|
|
|
1022
|
-
|
|
438
|
+
iterations:
|
|
439
|
+
small: 20
|
|
440
|
+
medium: 5
|
|
441
|
+
large: 2
|
|
1023
442
|
|
|
1024
|
-
|
|
443
|
+
operations:
|
|
444
|
+
- parse
|
|
445
|
+
- generate
|
|
446
|
+
- streaming
|
|
447
|
+
- memory
|
|
1025
448
|
|
|
1026
|
-
|
|
1027
|
-
----
|
|
1028
|
-
$ serialbench merge_results ruby-3.0/results ruby-3.1/results ruby-3.2/results merged_output/
|
|
449
|
+
warmup: 3
|
|
1029
450
|
----
|
|
1030
451
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
[source]
|
|
1034
|
-
----
|
|
1035
|
-
$ serialbench github_pages ruby-3.0/results ruby-3.1/results ruby-3.2/results docs/
|
|
1036
|
-
----
|
|
1037
|
-
|
|
1038
|
-
This creates an interactive HTML report with:
|
|
1039
|
-
|
|
1040
|
-
* **Multi-version charts**: Compare performance across Ruby versions
|
|
1041
|
-
* **Interactive navigation**: Switch between parsing, generation, streaming, and memory usage
|
|
1042
|
-
* **Environment details**: Ruby versions, platforms, and serializer versions
|
|
1043
|
-
* **GitHub Pages ready**: Deploy directly to GitHub Pages for public sharing
|
|
1044
|
-
|
|
1045
|
-
=== Cross-platform performance analysis
|
|
1046
|
-
|
|
1047
|
-
Analyze performance data from multiple benchmark runs across different platforms and Ruby versions:
|
|
1048
|
-
|
|
1049
|
-
[source]
|
|
1050
|
-
----
|
|
1051
|
-
$ serialbench analyze_performance artifacts/benchmark-results-*/ performance_analysis.json
|
|
1052
|
-
----
|
|
452
|
+
== Results structure
|
|
1053
453
|
|
|
1054
|
-
|
|
454
|
+
=== Individual run results
|
|
1055
455
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
* **Generates comprehensive JSON** with detailed performance metrics
|
|
1059
|
-
* **Handles both parsing and generation** benchmark results
|
|
1060
|
-
* **Provides summary statistics** about processed data
|
|
456
|
+
Results are stored in a structured directory format, with each run containing
|
|
457
|
+
raw benchmark data and execution logs.
|
|
1061
458
|
|
|
1062
|
-
|
|
459
|
+
The directory is located at `results/runs/{name}/`, where `{name}` is the name
|
|
460
|
+
of the environment used for the benchmark.
|
|
1063
461
|
|
|
1064
462
|
[source]
|
|
1065
463
|
----
|
|
1066
|
-
|
|
464
|
+
results/runs/docker-ruby-33-results/
|
|
465
|
+
├── results.yaml # Raw benchmark data
|
|
466
|
+
└── benchmark.log # Execution log
|
|
1067
467
|
----
|
|
1068
468
|
|
|
1069
|
-
|
|
469
|
+
=== ResultSet structure
|
|
1070
470
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
* **Sample counts**: Number of data points for statistical confidence
|
|
1075
|
-
* **Standard deviation**: Statistical variance for performance consistency
|
|
1076
|
-
|
|
1077
|
-
==== Example workflow for cross-platform analysis
|
|
471
|
+
ResultSets aggregate multiple benchmark runs for comparison. They are stored in
|
|
472
|
+
a structured directory format at `results/sets/{name}/`, where `{name}` is the
|
|
473
|
+
name of the result set.
|
|
1078
474
|
|
|
1079
475
|
[source]
|
|
1080
476
|
----
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
# 2. Collect results from multiple platforms/Ruby versions
|
|
1085
|
-
$ mkdir analysis
|
|
1086
|
-
$ cp -r platform1-ruby3.2/results analysis/benchmark-results-ubuntu-ruby-3.2
|
|
1087
|
-
$ cp -r platform2-ruby3.3/results analysis/benchmark-results-macos-ruby-3.3
|
|
1088
|
-
$ cp -r platform3-ruby3.4/results analysis/benchmark-results-windows-ruby-3.4
|
|
1089
|
-
|
|
1090
|
-
# 3. Generate performance analysis
|
|
1091
|
-
$ serialbench analyze_performance analysis/benchmark-results-*/ performance_analysis.json
|
|
1092
|
-
|
|
1093
|
-
# 4. Create platform comparison report
|
|
1094
|
-
$ serialbench platform_comparison performance_analysis.json platform_comparison.json
|
|
1095
|
-
|
|
1096
|
-
# 5. View results
|
|
1097
|
-
$ cat performance_analysis.json | jq '.summary'
|
|
1098
|
-
$ cat performance_analysis.json | jq '.platforms'
|
|
1099
|
-
$ cat platform_comparison.json | jq '.platforms'
|
|
1100
|
-
----
|
|
1101
|
-
|
|
1102
|
-
The analysis commands are particularly useful for:
|
|
1103
|
-
|
|
1104
|
-
* **CI/CD integration**: Automated cross-platform performance tracking
|
|
1105
|
-
* **Performance regression detection**: Compare results across builds
|
|
1106
|
-
* **Platform optimization**: Identify platform-specific performance characteristics
|
|
1107
|
-
* **Ruby version migration**: Analyze performance impact of Ruby upgrades
|
|
1108
|
-
|
|
1109
|
-
=== Programmatic usage
|
|
1110
|
-
|
|
1111
|
-
==== Basic benchmark execution
|
|
1112
|
-
|
|
1113
|
-
[source,ruby]
|
|
1114
|
-
----
|
|
1115
|
-
require 'serialbench'
|
|
1116
|
-
|
|
1117
|
-
# Run all benchmarks for all formats
|
|
1118
|
-
results = Serialbench.run_benchmarks
|
|
1119
|
-
|
|
1120
|
-
# Run benchmarks for specific formats
|
|
1121
|
-
results = Serialbench.run_benchmarks(formats: [:xml, :json])
|
|
1122
|
-
|
|
1123
|
-
# Generate comprehensive reports
|
|
1124
|
-
report_files = Serialbench.generate_reports(results)
|
|
1125
|
-
|
|
1126
|
-
puts "HTML report: #{report_files[:html]}"
|
|
1127
|
-
puts "Charts generated: #{report_files[:charts].length}"
|
|
1128
|
-
----
|
|
1129
|
-
|
|
1130
|
-
==== Custom benchmark configuration
|
|
1131
|
-
|
|
1132
|
-
[source,ruby]
|
|
1133
|
-
----
|
|
1134
|
-
require 'serialbench'
|
|
1135
|
-
|
|
1136
|
-
# Create a custom benchmark runner
|
|
1137
|
-
runner = Serialbench::BenchmarkRunner.new(formats: [:json, :xml])
|
|
1138
|
-
|
|
1139
|
-
# Run specific benchmark categories
|
|
1140
|
-
parsing_results = runner.run_parsing_benchmarks
|
|
1141
|
-
generation_results = runner.run_generation_benchmarks
|
|
1142
|
-
memory_results = runner.run_memory_benchmarks
|
|
1143
|
-
|
|
1144
|
-
# Format and display results
|
|
1145
|
-
formatter = Serialbench::ResultFormatter.new(runner.results)
|
|
1146
|
-
puts formatter.summary
|
|
1147
|
-
----
|
|
1148
|
-
|
|
1149
|
-
==== Individual serializer testing
|
|
1150
|
-
|
|
1151
|
-
[source,ruby]
|
|
1152
|
-
----
|
|
1153
|
-
require 'serialbench'
|
|
1154
|
-
|
|
1155
|
-
# Test a specific JSON serializer
|
|
1156
|
-
oj_serializer = Serialbench::Serializers::Json::OjSerializer.new
|
|
1157
|
-
|
|
1158
|
-
if oj_serializer.available?
|
|
1159
|
-
json_content = '{"users": [{"name": "Alice", "age": 30}]}'
|
|
1160
|
-
|
|
1161
|
-
# Parse JSON
|
|
1162
|
-
data = oj_serializer.parse(json_content)
|
|
1163
|
-
|
|
1164
|
-
# Generate JSON
|
|
1165
|
-
json_output = oj_serializer.generate(data, pretty: true)
|
|
1166
|
-
|
|
1167
|
-
# Stream parsing (if supported)
|
|
1168
|
-
if oj_serializer.supports_streaming?
|
|
1169
|
-
oj_serializer.stream_parse(json_content) do |event, data|
|
|
1170
|
-
puts "Event: #{event}, Data: #{data}"
|
|
1171
|
-
end
|
|
1172
|
-
end
|
|
1173
|
-
|
|
1174
|
-
puts "Serializer: #{oj_serializer.name}"
|
|
1175
|
-
puts "Version: #{oj_serializer.version}"
|
|
1176
|
-
puts "Format: #{oj_serializer.format}"
|
|
1177
|
-
puts "Features: #{oj_serializer.features}"
|
|
1178
|
-
end
|
|
1179
|
-
----
|
|
1180
|
-
|
|
1181
|
-
==== Check available serializers
|
|
1182
|
-
|
|
1183
|
-
[source,ruby]
|
|
1184
|
-
----
|
|
1185
|
-
require 'serialbench'
|
|
1186
|
-
|
|
1187
|
-
# List all available serializers
|
|
1188
|
-
Serialbench.available_serializers.each do |serializer_class|
|
|
1189
|
-
serializer = serializer_class.new
|
|
1190
|
-
puts "#{serializer.format}: #{serializer.name} v#{serializer.version}"
|
|
1191
|
-
end
|
|
1192
|
-
|
|
1193
|
-
# List serializers for specific format
|
|
1194
|
-
Serialbench.available_serializers(:json).each do |serializer_class|
|
|
1195
|
-
serializer = serializer_class.new
|
|
1196
|
-
puts "JSON: #{serializer.name} v#{serializer.version}"
|
|
1197
|
-
end
|
|
477
|
+
results/sets/ruby-version-comparison/
|
|
478
|
+
└── resultset.yml # Result set configuration
|
|
1198
479
|
----
|
|
1199
480
|
|
|
1200
481
|
== Benchmark categories
|
|
@@ -1221,105 +502,32 @@ it, which processes data sequentially and is memory-efficient for large files.
|
|
|
1221
502
|
Profiles memory allocation and retention during serialization operations using
|
|
1222
503
|
the `memory_profiler` gem.
|
|
1223
504
|
|
|
505
|
+
== Interactive Dashboard Features
|
|
1224
506
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
=== Generated files
|
|
1228
|
-
|
|
1229
|
-
Running benchmarks creates the following output structure:
|
|
507
|
+
The generated HTML sites provide comprehensive interactive dashboards with:
|
|
1230
508
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
│ └── benchmark_report.adoc # AsciiDoc source
|
|
1237
|
-
├── charts/
|
|
1238
|
-
│ ├── parsing_performance.svg
|
|
1239
|
-
│ ├── generation_performance.svg
|
|
1240
|
-
│ ├── streaming_performance.svg
|
|
1241
|
-
│ ├── memory_usage_comparison.svg
|
|
1242
|
-
│ └── format_comparison.svg
|
|
1243
|
-
├── data/
|
|
1244
|
-
│ ├── results.json # Raw benchmark data
|
|
1245
|
-
│ └── results.csv # CSV export
|
|
1246
|
-
└── assets/
|
|
1247
|
-
└── css/
|
|
1248
|
-
└── benchmark_report.css # Report styling
|
|
1249
|
-
----
|
|
1250
|
-
|
|
1251
|
-
=== Report features
|
|
1252
|
-
|
|
1253
|
-
* **Multi-format comparison**: Compare XML, JSON, and TOML performance
|
|
1254
|
-
* **Interactive charts**: SVG-based performance visualizations
|
|
1255
|
-
* **Comparative analysis**: Side-by-side library comparisons
|
|
1256
|
-
* **Performance rankings**: Fastest to slowest for each category
|
|
1257
|
-
* **Memory profiling**: Detailed memory allocation analysis
|
|
1258
|
-
* **Feature matrix**: Capability comparison across libraries
|
|
1259
|
-
* **Environment details**: Ruby version, platform, and library versions
|
|
1260
|
-
|
|
1261
|
-
=== Sample output
|
|
1262
|
-
|
|
1263
|
-
[example]
|
|
1264
|
-
====
|
|
1265
|
-
Serialbench - Comprehensive Serialization Performance Tests
|
|
1266
|
-
===========================================================
|
|
1267
|
-
Environment: Ruby 3.3.2 on arm64-darwin23
|
|
1268
|
-
Timestamp: 2025-06-07T10:30:00Z
|
|
1269
|
-
|
|
1270
|
-
Available serializers: rexml, json, oj, toml-rb
|
|
1271
|
-
Test formats: xml, json, toml
|
|
1272
|
-
Test data sizes: small, medium, large
|
|
1273
|
-
|
|
1274
|
-
Parsing Performance:
|
|
1275
|
-
Small files:
|
|
1276
|
-
JSON/oj: 0.08ms
|
|
1277
|
-
JSON/json: 0.12ms
|
|
1278
|
-
XML/rexml: 0.45ms
|
|
1279
|
-
TOML/toml-rb: 0.52ms
|
|
1280
|
-
|
|
1281
|
-
Medium files:
|
|
1282
|
-
JSON/oj: 8.23ms
|
|
1283
|
-
JSON/json: 12.67ms
|
|
1284
|
-
XML/rexml: 28.45ms
|
|
1285
|
-
TOML/toml-rb: 35.21ms
|
|
1286
|
-
====
|
|
1287
|
-
|
|
1288
|
-
== Methodology
|
|
509
|
+
=== Navigation and Filtering
|
|
510
|
+
* **Format tabs**: Dedicated views for XML, JSON, YAML, and TOML
|
|
511
|
+
* **Operation sections**: Parsing, generation, streaming, and memory usage
|
|
512
|
+
* **Dynamic filtering**: Platform, Ruby version, and environment selection
|
|
513
|
+
* **Real-time updates**: Charts update instantly based on filter selections
|
|
1289
514
|
|
|
1290
|
-
===
|
|
515
|
+
=== Visualization Capabilities
|
|
516
|
+
* **Chart.js integration**: Interactive performance charts with hover details
|
|
517
|
+
* **Multi-scale handling**: Automatic Y-axis scaling for different performance ranges
|
|
518
|
+
* **Color-coded data**: Consistent color schemes across serializers and environments
|
|
519
|
+
* **Responsive design**: Optimized for desktop and mobile viewing
|
|
1291
520
|
|
|
1292
|
-
|
|
1293
|
-
*
|
|
1294
|
-
*
|
|
1295
|
-
*
|
|
521
|
+
=== User Experience
|
|
522
|
+
* **Theme toggle**: Light and dark mode with persistent preferences
|
|
523
|
+
* **Keyboard navigation**: Full accessibility support
|
|
524
|
+
* **Fast loading**: Optimized JavaScript for quick dashboard initialization
|
|
525
|
+
* **Export capabilities**: JSON data export for further analysis
|
|
1296
526
|
|
|
1297
|
-
=== Test data
|
|
1298
|
-
|
|
1299
|
-
==== Synthetic datasets
|
|
1300
|
-
|
|
1301
|
-
The benchmark suite uses carefully crafted synthetic data that represents common real-world scenarios:
|
|
1302
|
-
|
|
1303
|
-
* **Configuration files**: Small, nested structures typical of application settings
|
|
1304
|
-
* **API responses**: Medium-sized documents with repeated record structures
|
|
1305
|
-
* **Data exports**: Large documents with extensive hierarchical data
|
|
1306
|
-
|
|
1307
|
-
==== Multi-format consistency
|
|
1308
|
-
|
|
1309
|
-
* Equivalent data structures across XML, JSON, and TOML formats
|
|
1310
|
-
* Consistent complexity and nesting levels
|
|
1311
|
-
* Representative of real-world usage patterns
|
|
1312
|
-
|
|
1313
|
-
=== Statistical considerations
|
|
1314
|
-
|
|
1315
|
-
* Multiple iterations reduce timing variance
|
|
1316
|
-
* Warmup iterations eliminate JIT compilation effects
|
|
1317
|
-
* Memory measurements account for garbage collection
|
|
1318
|
-
* Results include both absolute and relative performance metrics
|
|
1319
527
|
|
|
1320
528
|
== Development
|
|
1321
529
|
|
|
1322
|
-
=== Running
|
|
530
|
+
=== Running Tests
|
|
1323
531
|
|
|
1324
532
|
[source]
|
|
1325
533
|
----
|
|
@@ -1327,15 +535,7 @@ $ bundle exec rake
|
|
|
1327
535
|
$ bundle exec rspec
|
|
1328
536
|
----
|
|
1329
537
|
|
|
1330
|
-
===
|
|
1331
|
-
|
|
1332
|
-
. Fork the repository
|
|
1333
|
-
. Create your feature branch (`git checkout -b feature/my-new-feature`)
|
|
1334
|
-
. Commit your changes (`git commit -am 'Add some feature'`)
|
|
1335
|
-
. Push to the branch (`git push origin feature/my-new-feature`)
|
|
1336
|
-
. Create a new Pull Request
|
|
1337
|
-
|
|
1338
|
-
=== Adding new serializers
|
|
538
|
+
=== Adding a new serializers
|
|
1339
539
|
|
|
1340
540
|
To add support for additional serialization libraries:
|
|
1341
541
|
|
|
@@ -1345,76 +545,50 @@ To add support for additional serialization libraries:
|
|
|
1345
545
|
. Add the serializer to the registry in `lib/serialbench/serializers.rb`
|
|
1346
546
|
. Update documentation and tests
|
|
1347
547
|
|
|
1348
|
-
|
|
548
|
+
=== Contributing
|
|
1349
549
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
require_library('yajl')
|
|
1356
|
-
end
|
|
1357
|
-
|
|
1358
|
-
def name
|
|
1359
|
-
'yajl'
|
|
1360
|
-
end
|
|
1361
|
-
|
|
1362
|
-
def version
|
|
1363
|
-
require 'yajl'
|
|
1364
|
-
Yajl::VERSION
|
|
1365
|
-
end
|
|
1366
|
-
|
|
1367
|
-
def parse(json_string)
|
|
1368
|
-
require 'yajl'
|
|
1369
|
-
Yajl::Parser.parse(json_string)
|
|
1370
|
-
end
|
|
1371
|
-
|
|
1372
|
-
def generate(object, options = {})
|
|
1373
|
-
require 'yajl'
|
|
1374
|
-
Yajl::Encoder.encode(object)
|
|
1375
|
-
end
|
|
1376
|
-
end
|
|
1377
|
-
----
|
|
550
|
+
. Fork the repository
|
|
551
|
+
. Create your feature branch (`git checkout -b feature/my-new-feature`)
|
|
552
|
+
. Commit your changes (`git commit -am 'Add some feature'`)
|
|
553
|
+
. Push to the branch (`git push origin feature/my-new-feature`)
|
|
554
|
+
. Create a new Pull Request
|
|
1378
555
|
|
|
1379
|
-
== Architecture
|
|
1380
556
|
|
|
1381
|
-
|
|
557
|
+
== Known issues
|
|
1382
558
|
|
|
1383
|
-
|
|
1384
|
-
----
|
|
1385
|
-
BaseSerializer
|
|
1386
|
-
├── BaseXmlSerializer
|
|
1387
|
-
│ └── RexmlSerializer
|
|
1388
|
-
├── BaseJsonSerializer
|
|
1389
|
-
│ ├── JsonSerializer
|
|
1390
|
-
│ └── OjSerializer
|
|
1391
|
-
└── BaseTomlSerializer
|
|
1392
|
-
└── TomlRbSerializer
|
|
1393
|
-
----
|
|
559
|
+
=== Syck YAML serializer segmentation faults
|
|
1394
560
|
|
|
1395
|
-
|
|
561
|
+
The Syck YAML serializer at version 1.5+ is known to cause segmentation faults
|
|
562
|
+
on Ruby 3.1 and later versions. Serialbench automatically detects this
|
|
563
|
+
problematic configuration and:
|
|
1396
564
|
|
|
1397
|
-
*
|
|
1398
|
-
*
|
|
1399
|
-
*
|
|
1400
|
-
* **ReportGenerator**: Creates HTML/AsciiDoc reports
|
|
1401
|
-
* **ChartGenerator**: Creates performance visualizations
|
|
1402
|
-
* **MemoryProfiler**: Analyzes memory usage patterns
|
|
565
|
+
* Displays a warning message when Syck is detected on Ruby 3.1+
|
|
566
|
+
* Skips Syck benchmarks to prevent crashes
|
|
567
|
+
* Continues with other YAML serializers (Psych)
|
|
1403
568
|
|
|
1404
|
-
|
|
569
|
+
=== Syck overrides YAML constant
|
|
1405
570
|
|
|
1406
|
-
|
|
571
|
+
On occasion after Syck is loaded, the constant `YAML` may be redefined to
|
|
572
|
+
`Syck`, which can cause issues in other parts of the codebase. This can cause
|
|
573
|
+
YAML output to fail when using libraries that expect `YAML` to have the
|
|
574
|
+
`Psych` API.
|
|
575
|
+
|
|
576
|
+
In `benchmark_cli.rb` there is therefore such code to ensure that
|
|
577
|
+
`YAML` is defined as `Psych` when writing to file is needed:
|
|
578
|
+
|
|
579
|
+
[source,ruby]
|
|
580
|
+
----
|
|
581
|
+
# Restore YAML to use Psych for output, otherwise lutaml-model's to_yaml
|
|
582
|
+
# will have no output
|
|
583
|
+
Object.const_set(:YAML, Psych)
|
|
584
|
+
----
|
|
1407
585
|
|
|
1408
|
-
* https://www.ohler.com/dev/xml_with_ruby/xml_with_ruby.html[XML with Ruby performance analysis]
|
|
1409
|
-
* https://gist.github.com/danneu/3977120[Ruby XML parser comparison]
|
|
1410
|
-
* https://gist.github.com/adilosa/d4277dc1c683da91990515352ffe5420[XML parsing benchmarks]
|
|
1411
586
|
|
|
1412
|
-
==
|
|
587
|
+
== License and copyright
|
|
1413
588
|
|
|
1414
|
-
|
|
1415
|
-
https://www.ribose.com[Ribose Inc.]
|
|
589
|
+
Copyright Ribose.
|
|
1416
590
|
|
|
1417
|
-
|
|
591
|
+
This gem is developed, maintained and funded by https://www.ribose.com[Ribose]
|
|
1418
592
|
|
|
1419
593
|
The gem is available as open source under the terms of the
|
|
1420
594
|
https://opensource.org/licenses/BSD-2-Clause[2-Clause BSD License].
|