serialbench 0.3.1 → 0.4.0
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 +0 -20
- data/Gemfile +1 -1
- data/lib/serialbench/benchmark_runner.rb +12 -297
- data/lib/serialbench/cli.rb +0 -5
- data/lib/serialbench/models/result_store.rb +0 -38
- data/lib/serialbench/models.rb +0 -5
- data/lib/serialbench/serializers/base_serializer.rb +0 -4
- data/lib/serialbench/serializers/json/base_json_serializer.rb +8 -20
- data/lib/serialbench/serializers/json/json_serializer.rb +0 -16
- data/lib/serialbench/serializers/json/oj_serializer.rb +2 -17
- data/lib/serialbench/serializers/json/yajl_serializer.rb +2 -2
- data/lib/serialbench/serializers/toml/base_toml_serializer.rb +8 -29
- data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +0 -16
- data/lib/serialbench/serializers/toml/tomlib_serializer.rb +0 -4
- data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +2 -18
- data/lib/serialbench/serializers/xml/base_xml_serializer.rb +4 -16
- data/lib/serialbench/serializers/xml/leptris_serializer.rb +1 -5
- data/lib/serialbench/serializers/xml/libxml_serializer.rb +4 -9
- data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +3 -3
- data/lib/serialbench/serializers/xml/oga_serializer.rb +3 -5
- data/lib/serialbench/serializers/xml/ox_serializer.rb +2 -2
- data/lib/serialbench/serializers/xml/rexml_serializer.rb +5 -12
- data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +1 -9
- data/lib/serialbench/serializers/yaml/syck_serializer.rb +0 -8
- data/lib/serialbench/test_data.rb +315 -0
- data/lib/serialbench/version.rb +1 -1
- data/lib/serialbench.rb +2 -1
- data/serialbench.gemspec +1 -2
- metadata +6 -22
- data/lib/serialbench/cli/resultset_cli.rb +0 -301
- data/lib/serialbench/models/result_set.rb +0 -79
- data/lib/serialbench/site_generator.rb +0 -337
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e90d8b6ebc8deebf308b1e02214b978597d0d2a9699c3845ebf6405953d733b7
|
|
4
|
+
data.tar.gz: 4cc9e46139f7054919657d66fd26ed6b40430856e0bdd317f2677451bc1bf715
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38652e0714893c8ed9590fe1a7ef29c9c6e94cdbdcb0104d9190d12bad1c95f8635680b904d66b9edda72f55f7c037ce5e18894bf5fb66d5b88db21ba2dcaa3d
|
|
7
|
+
data.tar.gz: 728e8ee7c92138afdfd722cfb93ef7463c22e7d1c8882e5d83507dba7861637addd659e489df21c91a80a45680fc532eb0898f9ffed9ce48402a604962b73c85
|
|
@@ -111,26 +111,6 @@ jobs:
|
|
|
111
111
|
- name: Install gems
|
|
112
112
|
run: bundle install
|
|
113
113
|
|
|
114
|
-
- name: Build libleptris from source (Ubuntu 22.04)
|
|
115
|
-
if: matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-22.04-arm'
|
|
116
|
-
run: |
|
|
117
|
-
LEPTRIS_VERSION=$(bundle exec ruby -e "print Gem::Specification.find_by_name('leptris').version")
|
|
118
|
-
LEPTRIS_TAG=$(curl -s "https://api.github.com/repos/leptris/leptris/tags?per_page=100" \
|
|
119
|
-
| grep -oE '"v[0-9]+\.[0-9]+\.[0-9]+"' | tr -d '"' | sort -V \
|
|
120
|
-
| awk -v v="v${LEPTRIS_VERSION}" '$0 <= v' | tail -1)
|
|
121
|
-
echo "Building libleptris ${LEPTRIS_VERSION} from tag ${LEPTRIS_TAG}"
|
|
122
|
-
test -n "${LEPTRIS_TAG}"
|
|
123
|
-
curl -sL "https://github.com/leptris/leptris/archive/refs/tags/${LEPTRIS_TAG}.tar.gz" | tar xz
|
|
124
|
-
ln -s "leptris-${LEPTRIS_TAG#v}" "leptris-${LEPTRIS_VERSION}"
|
|
125
|
-
cmake -S "leptris-${LEPTRIS_VERSION}" -B /tmp/leptris-build \
|
|
126
|
-
-DLEPTRIS_BUILD_SHARED=ON -DLEPTRIS_BUILD_STATIC=OFF -DBUILD_TESTING=OFF \
|
|
127
|
-
-DLEPTRIS_BUILD_CLI=OFF -DLEPTRIS_BUILD_BENCHMARKS=OFF -DLEPTRIS_BUILD_MAN_PAGES=OFF \
|
|
128
|
-
-DLEPTRIS_ENABLE_UTF8PROC=OFF -DLEPTRIS_ENABLE_ICONV=OFF
|
|
129
|
-
cmake --build /tmp/leptris-build -j"$(nproc)"
|
|
130
|
-
LIBLEPTRIS=$(find /tmp/leptris-build -name 'libleptris.so*' -type f | head -1)
|
|
131
|
-
echo "LEPTRIS_LIB_PATH=${LIBLEPTRIS}" >> "$GITHUB_ENV"
|
|
132
|
-
shell: bash
|
|
133
|
-
|
|
134
114
|
- name: Create environment config
|
|
135
115
|
run: |
|
|
136
116
|
mkdir -p config/environments
|
data/Gemfile
CHANGED
|
@@ -12,7 +12,7 @@ unless Gem.win_platform? && RUBY_PLATFORM.include?('aarch64')
|
|
|
12
12
|
gem 'libxml-ruby'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
gem 'leptris', '1.9.
|
|
15
|
+
gem 'leptris', '1.9.35' # precompiled platform gems bundle libleptris (darwin/linux/mingw)
|
|
16
16
|
gem 'benchmark' # Removed from stdlib in Ruby 4.0
|
|
17
17
|
gem 'base64' # Required for Ruby 3.4+
|
|
18
18
|
gem 'lutaml-model', '~> 0.7'
|
|
@@ -145,313 +145,28 @@ module Serialbench
|
|
|
145
145
|
|
|
146
146
|
case type_name
|
|
147
147
|
when 'generation'
|
|
148
|
-
serializers.select(
|
|
148
|
+
serializers.select { |s| s.supports?(:generate) }
|
|
149
149
|
when 'streaming'
|
|
150
|
-
serializers.select(
|
|
150
|
+
serializers.select { |s| s.supports?(:sax) || s.supports?(:streaming) }
|
|
151
|
+
when 'xpath'
|
|
152
|
+
serializers.select { |s| s.supports?(:xpath) }
|
|
151
153
|
else
|
|
152
154
|
serializers
|
|
153
155
|
end
|
|
154
156
|
end
|
|
155
157
|
|
|
156
158
|
def get_iterations_for_size(size)
|
|
157
|
-
@benchmark_config.iterations
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# Initialize test data structure
|
|
165
|
-
@test_data = {}
|
|
166
|
-
data_sizes.each { |size| @test_data[size] = {} }
|
|
167
|
-
|
|
168
|
-
# Generate data for each format and size
|
|
169
|
-
@benchmark_config.formats.each do |format|
|
|
170
|
-
data_sizes.each do |size|
|
|
171
|
-
@test_data[size][format] = generate_test_data(format, size)
|
|
172
|
-
end
|
|
159
|
+
iterations = @benchmark_config.iterations
|
|
160
|
+
case size.to_s
|
|
161
|
+
when 'small' then iterations.small
|
|
162
|
+
when 'medium' then iterations.medium
|
|
163
|
+
when 'large' then iterations.large
|
|
164
|
+
else raise ArgumentError, "no iteration count configured for #{size}"
|
|
173
165
|
end
|
|
174
|
-
|
|
175
|
-
# Try to load real test files if they exist
|
|
176
|
-
data_sizes.each do |size|
|
|
177
|
-
@benchmark_config.formats.each do |format|
|
|
178
|
-
file_path = "test_data/#{size}.#{format}"
|
|
179
|
-
@test_data[size][format] = File.read(file_path) if File.exist?(file_path)
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def generate_test_data(format, size)
|
|
185
|
-
method_name = "generate_#{size}_#{format}"
|
|
186
|
-
send(method_name)
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# Shared data structure generators
|
|
190
|
-
def small_test_data_structure
|
|
191
|
-
{
|
|
192
|
-
config: {
|
|
193
|
-
database: {
|
|
194
|
-
host: 'localhost',
|
|
195
|
-
port: 5432,
|
|
196
|
-
name: 'myapp',
|
|
197
|
-
user: 'admin',
|
|
198
|
-
password: 'secret'
|
|
199
|
-
},
|
|
200
|
-
cache: {
|
|
201
|
-
enabled: true,
|
|
202
|
-
ttl: 3600
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def medium_test_data_structure
|
|
209
|
-
{
|
|
210
|
-
users: (1..1000).map do |i|
|
|
211
|
-
{
|
|
212
|
-
id: i,
|
|
213
|
-
name: "User #{i}",
|
|
214
|
-
email: "user#{i}@example.com",
|
|
215
|
-
created_at: "2023-01-#{(i % 28) + 1}T10:00:00Z",
|
|
216
|
-
profile: {
|
|
217
|
-
age: 20 + (i % 50),
|
|
218
|
-
city: "City #{i % 100}",
|
|
219
|
-
preferences: {
|
|
220
|
-
theme: i.even? ? 'dark' : 'light',
|
|
221
|
-
notifications: (i % 3).zero?
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
end
|
|
226
|
-
}
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def large_test_data_structure
|
|
230
|
-
{
|
|
231
|
-
dataset: {
|
|
232
|
-
header: {
|
|
233
|
-
created: '2023-01-01T00:00:00Z',
|
|
234
|
-
count: 10_000,
|
|
235
|
-
format: 'data'
|
|
236
|
-
},
|
|
237
|
-
records: (1..10_000).map do |i|
|
|
238
|
-
{
|
|
239
|
-
id: i,
|
|
240
|
-
timestamp: "2023-01-01T#{format('%02d', i % 24)}:#{format('%02d', i % 60)}:#{format('%02d', i % 60)}Z",
|
|
241
|
-
data: {
|
|
242
|
-
field1: "Value #{i}",
|
|
243
|
-
field2: i * 2,
|
|
244
|
-
field3: (i % 100).zero? ? 'special' : 'normal',
|
|
245
|
-
nested: [
|
|
246
|
-
"Item #{i}-1",
|
|
247
|
-
"Item #{i}-2",
|
|
248
|
-
"Item #{i}-3"
|
|
249
|
-
]
|
|
250
|
-
},
|
|
251
|
-
metadata: {
|
|
252
|
-
source: 'generator',
|
|
253
|
-
version: '1.0',
|
|
254
|
-
checksum: i.to_s(16)
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
end
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
# XML test data generators
|
|
263
|
-
def generate_small_xml
|
|
264
|
-
data = small_test_data_structure
|
|
265
|
-
<<~XML
|
|
266
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
267
|
-
<config>
|
|
268
|
-
<database>
|
|
269
|
-
<host>#{data[:config][:database][:host]}</host>
|
|
270
|
-
<port>#{data[:config][:database][:port]}</port>
|
|
271
|
-
<name>#{data[:config][:database][:name]}</name>
|
|
272
|
-
<user>#{data[:config][:database][:user]}</user>
|
|
273
|
-
<password>#{data[:config][:database][:password]}</password>
|
|
274
|
-
</database>
|
|
275
|
-
<cache>
|
|
276
|
-
<enabled>#{data[:config][:cache][:enabled]}</enabled>
|
|
277
|
-
<ttl>#{data[:config][:cache][:ttl]}</ttl>
|
|
278
|
-
</cache>
|
|
279
|
-
</config>
|
|
280
|
-
XML
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
def generate_medium_xml
|
|
284
|
-
data = medium_test_data_structure
|
|
285
|
-
users = data[:users].map do |user|
|
|
286
|
-
<<~USER
|
|
287
|
-
<user id="#{user[:id]}">
|
|
288
|
-
<name>#{user[:name]}</name>
|
|
289
|
-
<email>#{user[:email]}</email>
|
|
290
|
-
<created_at>#{user[:created_at]}</created_at>
|
|
291
|
-
<profile>
|
|
292
|
-
<age>#{user[:profile][:age]}</age>
|
|
293
|
-
<city>#{user[:profile][:city]}</city>
|
|
294
|
-
<preferences>
|
|
295
|
-
<theme>#{user[:profile][:preferences][:theme]}</theme>
|
|
296
|
-
<notifications>#{user[:profile][:preferences][:notifications]}</notifications>
|
|
297
|
-
</preferences>
|
|
298
|
-
</profile>
|
|
299
|
-
</user>
|
|
300
|
-
USER
|
|
301
|
-
end.join
|
|
302
|
-
|
|
303
|
-
<<~XML
|
|
304
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
305
|
-
<users>
|
|
306
|
-
#{users}
|
|
307
|
-
</users>
|
|
308
|
-
XML
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
def generate_large_xml
|
|
312
|
-
data = large_test_data_structure
|
|
313
|
-
records = data[:dataset][:records].map do |record|
|
|
314
|
-
nested_items = record[:data][:nested].map { |item| " <item>#{item}</item>" }.join("\n")
|
|
315
|
-
<<~RECORD
|
|
316
|
-
<record id="#{record[:id]}">
|
|
317
|
-
<timestamp>#{record[:timestamp]}</timestamp>
|
|
318
|
-
<data>
|
|
319
|
-
<field1>#{record[:data][:field1]}</field1>
|
|
320
|
-
<field2>#{record[:data][:field2]}</field2>
|
|
321
|
-
<field3>#{record[:data][:field3]}</field3>
|
|
322
|
-
<nested>
|
|
323
|
-
#{nested_items}
|
|
324
|
-
</nested>
|
|
325
|
-
</data>
|
|
326
|
-
<metadata>
|
|
327
|
-
<source>#{record[:metadata][:source]}</source>
|
|
328
|
-
<version>#{record[:metadata][:version]}</version>
|
|
329
|
-
<checksum>#{record[:metadata][:checksum]}</checksum>
|
|
330
|
-
</metadata>
|
|
331
|
-
</record>
|
|
332
|
-
RECORD
|
|
333
|
-
end.join
|
|
334
|
-
|
|
335
|
-
<<~XML
|
|
336
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
337
|
-
<dataset>
|
|
338
|
-
<header>
|
|
339
|
-
<created>#{data[:dataset][:header][:created]}</created>
|
|
340
|
-
<count>#{data[:dataset][:header][:count]}</count>
|
|
341
|
-
<format>xml</format>
|
|
342
|
-
</header>
|
|
343
|
-
<records>
|
|
344
|
-
#{records}
|
|
345
|
-
</records>
|
|
346
|
-
</dataset>
|
|
347
|
-
XML
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
# JSON test data generators
|
|
351
|
-
def generate_small_json
|
|
352
|
-
JSON.generate(small_test_data_structure)
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
def generate_medium_json
|
|
356
|
-
JSON.generate(medium_test_data_structure)
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
def generate_large_json
|
|
360
|
-
data = large_test_data_structure
|
|
361
|
-
data[:dataset][:header][:format] = 'json'
|
|
362
|
-
JSON.generate(data)
|
|
363
166
|
end
|
|
364
167
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
small_test_data_structure.to_yaml
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
def generate_medium_yaml
|
|
371
|
-
medium_test_data_structure.to_yaml
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
def generate_large_yaml
|
|
375
|
-
data = large_test_data_structure
|
|
376
|
-
data[:dataset][:header][:format] = 'yaml'
|
|
377
|
-
data.to_yaml
|
|
378
|
-
end
|
|
379
|
-
|
|
380
|
-
# TOML test data generators
|
|
381
|
-
def generate_small_toml
|
|
382
|
-
data = small_test_data_structure
|
|
383
|
-
<<~TOML
|
|
384
|
-
[config]
|
|
385
|
-
|
|
386
|
-
[config.database]
|
|
387
|
-
host = "#{data[:config][:database][:host]}"
|
|
388
|
-
port = #{data[:config][:database][:port]}
|
|
389
|
-
name = "#{data[:config][:database][:name]}"
|
|
390
|
-
user = "#{data[:config][:database][:user]}"
|
|
391
|
-
password = "#{data[:config][:database][:password]}"
|
|
392
|
-
|
|
393
|
-
[config.cache]
|
|
394
|
-
enabled = #{data[:config][:cache][:enabled]}
|
|
395
|
-
ttl = #{data[:config][:cache][:ttl]}
|
|
396
|
-
TOML
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
def generate_medium_toml
|
|
400
|
-
data = medium_test_data_structure
|
|
401
|
-
# Use smaller dataset for TOML due to verbosity
|
|
402
|
-
users = data[:users].first(100)
|
|
403
|
-
users.map do |user|
|
|
404
|
-
<<~USER
|
|
405
|
-
[[users]]
|
|
406
|
-
id = #{user[:id]}
|
|
407
|
-
name = "#{user[:name]}"
|
|
408
|
-
email = "#{user[:email]}"
|
|
409
|
-
created_at = "#{user[:created_at]}"
|
|
410
|
-
|
|
411
|
-
[users.profile]
|
|
412
|
-
age = #{user[:profile][:age]}
|
|
413
|
-
city = "#{user[:profile][:city]}"
|
|
414
|
-
|
|
415
|
-
[users.profile.preferences]
|
|
416
|
-
theme = "#{user[:profile][:preferences][:theme]}"
|
|
417
|
-
notifications = #{user[:profile][:preferences][:notifications]}
|
|
418
|
-
USER
|
|
419
|
-
end.join("\n")
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
def generate_large_toml
|
|
423
|
-
data = large_test_data_structure
|
|
424
|
-
# Use smaller dataset for TOML due to verbosity
|
|
425
|
-
records = data[:dataset][:records].first(1000)
|
|
426
|
-
records_toml = records.map do |record|
|
|
427
|
-
<<~RECORD
|
|
428
|
-
[[dataset.records]]
|
|
429
|
-
id = #{record[:id]}
|
|
430
|
-
timestamp = "#{record[:timestamp]}"
|
|
431
|
-
|
|
432
|
-
[dataset.records.data]
|
|
433
|
-
field1 = "#{record[:data][:field1]}"
|
|
434
|
-
field2 = #{record[:data][:field2]}
|
|
435
|
-
field3 = "#{record[:data][:field3]}"
|
|
436
|
-
nested = #{record[:data][:nested].inspect}
|
|
437
|
-
|
|
438
|
-
[dataset.records.metadata]
|
|
439
|
-
source = "#{record[:metadata][:source]}"
|
|
440
|
-
version = "#{record[:metadata][:version]}"
|
|
441
|
-
checksum = "#{record[:metadata][:checksum]}"
|
|
442
|
-
RECORD
|
|
443
|
-
end.join("\n")
|
|
444
|
-
|
|
445
|
-
<<~TOML
|
|
446
|
-
[dataset]
|
|
447
|
-
|
|
448
|
-
[dataset.header]
|
|
449
|
-
created = "#{data[:dataset][:header][:created]}"
|
|
450
|
-
count = #{records.length}
|
|
451
|
-
format = "toml"
|
|
452
|
-
|
|
453
|
-
#{records_toml}
|
|
454
|
-
TOML
|
|
168
|
+
def load_test_data
|
|
169
|
+
@test_data = TestData.load(@benchmark_config)
|
|
455
170
|
end
|
|
456
171
|
end
|
|
457
172
|
end
|
data/lib/serialbench/cli.rb
CHANGED
|
@@ -6,7 +6,6 @@ require_relative 'cli/environment_cli'
|
|
|
6
6
|
require_relative 'cli/benchmark_cli'
|
|
7
7
|
require_relative 'cli/ruby_build_cli'
|
|
8
8
|
require_relative 'cli/validate_cli'
|
|
9
|
-
require_relative 'cli/resultset_cli'
|
|
10
9
|
|
|
11
10
|
module Serialbench
|
|
12
11
|
# Main CLI entry point for the new object-oriented command structure
|
|
@@ -58,10 +57,6 @@ module Serialbench
|
|
|
58
57
|
serialbench benchmark create my-benchmark
|
|
59
58
|
serialbench benchmark execute my-benchmark.yml
|
|
60
59
|
|
|
61
|
-
# Create a result set for comparison
|
|
62
|
-
|
|
63
|
-
# Generate static sites
|
|
64
|
-
serialbench benchmark build-site results/my-benchmark
|
|
65
60
|
|
|
66
61
|
For detailed help on any command, use:
|
|
67
62
|
serialbench COMMAND help
|
|
@@ -8,7 +8,6 @@ module Serialbench
|
|
|
8
8
|
class ResultStore
|
|
9
9
|
DEFAULT_BASE_PATH = 'results'
|
|
10
10
|
RUNS_PATH = 'runs'
|
|
11
|
-
SETS_PATH = 'sets'
|
|
12
11
|
|
|
13
12
|
attr_reader :base_path
|
|
14
13
|
|
|
@@ -34,27 +33,6 @@ module Serialbench
|
|
|
34
33
|
limit ? runs.first(limit) : runs
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
# Run set management
|
|
38
|
-
def sets_path
|
|
39
|
-
File.join(@base_path, SETS_PATH)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def find_resultsets(tags: nil, limit: nil)
|
|
43
|
-
resultsets = ResultSet.find_all(sets_path)
|
|
44
|
-
|
|
45
|
-
resultsets = resultsets.select { |resultset| (Array(tags) - resultset.tags).empty? } if tags
|
|
46
|
-
|
|
47
|
-
limit ? resultsets.first(limit) : resultsets
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Convenience methods
|
|
51
|
-
def create_resultset(name, run_platform_strings, metadata: {})
|
|
52
|
-
run_paths = run_platform_strings.map { |ps| File.join(runs_path, ps) }
|
|
53
|
-
resultset = ResultSet.create(name, run_paths, metadata: metadata)
|
|
54
|
-
save_resultset(resultset)
|
|
55
|
-
resultset
|
|
56
|
-
end
|
|
57
|
-
|
|
58
36
|
# Validation
|
|
59
37
|
def validate_structure
|
|
60
38
|
errors = []
|
|
@@ -62,7 +40,6 @@ module Serialbench
|
|
|
62
40
|
# Check base structure
|
|
63
41
|
errors << "Base path does not exist: #{@base_path}" unless Dir.exist?(@base_path)
|
|
64
42
|
errors << "Runs directory does not exist: #{runs_path}" unless Dir.exist?(runs_path)
|
|
65
|
-
errors << "Sets directory does not exist: #{sets_path}" unless Dir.exist?(sets_path)
|
|
66
43
|
|
|
67
44
|
# Validate individual runs
|
|
68
45
|
if Dir.exist?(runs_path)
|
|
@@ -78,20 +55,6 @@ module Serialbench
|
|
|
78
55
|
end
|
|
79
56
|
end
|
|
80
57
|
|
|
81
|
-
# Validate result sets
|
|
82
|
-
if Dir.exist?(sets_path)
|
|
83
|
-
Dir.glob(File.join(sets_path, '*')).each do |set_path|
|
|
84
|
-
next unless Dir.exist?(set_path)
|
|
85
|
-
|
|
86
|
-
begin
|
|
87
|
-
resultset = ResultSet.load(set_path)
|
|
88
|
-
resultset.validate!
|
|
89
|
-
rescue StandardError => e
|
|
90
|
-
errors << "Invalid result set at #{set_path}: #{e.message}"
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
58
|
errors
|
|
96
59
|
end
|
|
97
60
|
|
|
@@ -101,7 +64,6 @@ module Serialbench
|
|
|
101
64
|
|
|
102
65
|
def ensure_results_directory
|
|
103
66
|
FileUtils.mkdir_p(runs_path) unless Dir.exist?(runs_path)
|
|
104
|
-
FileUtils.mkdir_p(sets_path) unless Dir.exist?(sets_path)
|
|
105
67
|
end
|
|
106
68
|
end
|
|
107
69
|
end
|
data/lib/serialbench/models.rb
CHANGED
|
@@ -6,7 +6,6 @@ require_relative 'models/result'
|
|
|
6
6
|
require_relative 'models/result_store'
|
|
7
7
|
require_relative 'models/benchmark_config'
|
|
8
8
|
require_relative 'models/environment_config'
|
|
9
|
-
require_relative 'models/result_set'
|
|
10
9
|
|
|
11
10
|
module Serialbench
|
|
12
11
|
module Models
|
|
@@ -46,9 +45,5 @@ module Serialbench
|
|
|
46
45
|
def self.create_run(platform_string, benchmark_data, metadata: {})
|
|
47
46
|
Result.create(platform_string, benchmark_data, metadata: metadata)
|
|
48
47
|
end
|
|
49
|
-
|
|
50
|
-
def self.create_resultset(name, run_paths_or_objects, metadata: {})
|
|
51
|
-
ResultSet.create(name, run_paths_or_objects, metadata: metadata)
|
|
52
|
-
end
|
|
53
48
|
end
|
|
54
49
|
end
|
|
@@ -19,32 +19,20 @@ module Serialbench
|
|
|
19
19
|
generate(object, options)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def capabilities
|
|
23
|
+
super | Set.new(%i[pretty_print])
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
# JSON-specific features
|
|
23
27
|
def features
|
|
24
28
|
{
|
|
25
|
-
pretty_print:
|
|
26
|
-
streaming:
|
|
27
|
-
symbol_keys:
|
|
28
|
-
custom_types:
|
|
29
|
+
pretty_print: supports?(:pretty_print),
|
|
30
|
+
streaming: supports?(:sax) || supports?(:streaming),
|
|
31
|
+
symbol_keys: supports?(:symbol_keys),
|
|
32
|
+
custom_types: supports?(:custom_types)
|
|
29
33
|
}
|
|
30
34
|
end
|
|
31
35
|
|
|
32
|
-
def supports_generation?
|
|
33
|
-
true
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def supports_pretty_print?
|
|
37
|
-
true
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def supports_symbol_keys?
|
|
41
|
-
false
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def supports_custom_types?
|
|
45
|
-
false
|
|
46
|
-
end
|
|
47
|
-
|
|
48
36
|
# Subclasses should override this to specify their library name
|
|
49
37
|
def library_require_name
|
|
50
38
|
raise NotImplementedError, 'Subclasses must implement #library_require_name'
|
|
@@ -34,22 +34,6 @@ module Serialbench
|
|
|
34
34
|
JSON.generate(object)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
|
-
|
|
38
|
-
def supports_streaming?
|
|
39
|
-
false
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def supports_pretty_print?
|
|
43
|
-
true
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def supports_symbol_keys?
|
|
47
|
-
false
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def supports_custom_types?
|
|
51
|
-
false
|
|
52
|
-
end
|
|
53
37
|
end
|
|
54
38
|
end
|
|
55
39
|
end
|
|
@@ -46,23 +46,8 @@ module Serialbench
|
|
|
46
46
|
super
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def
|
|
50
|
-
|
|
51
|
-
Oj.respond_to?(:saj_parse)
|
|
52
|
-
rescue LoadError
|
|
53
|
-
false
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def supports_pretty_print?
|
|
57
|
-
true
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def supports_symbol_keys?
|
|
61
|
-
true
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def supports_custom_types?
|
|
65
|
-
true
|
|
49
|
+
def capabilities
|
|
50
|
+
super | Set.new(%i[symbol_keys custom_types sax])
|
|
66
51
|
end
|
|
67
52
|
end
|
|
68
53
|
|
|
@@ -19,41 +19,20 @@ module Serialbench
|
|
|
19
19
|
generate(object, options)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def capabilities
|
|
23
|
+
super | Set.new(%i[arrays_of_tables inline_tables multiline_strings])
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
# TOML-specific features
|
|
23
27
|
def features
|
|
24
28
|
{
|
|
25
|
-
comments:
|
|
26
|
-
arrays_of_tables:
|
|
27
|
-
inline_tables:
|
|
28
|
-
multiline_strings:
|
|
29
|
+
comments: supports?(:comments),
|
|
30
|
+
arrays_of_tables: supports?(:arrays_of_tables),
|
|
31
|
+
inline_tables: supports?(:inline_tables),
|
|
32
|
+
multiline_strings: supports?(:multiline_strings)
|
|
29
33
|
}
|
|
30
34
|
end
|
|
31
35
|
|
|
32
|
-
def supports_generation?
|
|
33
|
-
true
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def supports_streaming?
|
|
37
|
-
# TOML is typically not streamed due to its structure
|
|
38
|
-
false
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def supports_comments?
|
|
42
|
-
false
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def supports_arrays_of_tables?
|
|
46
|
-
true
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def supports_inline_tables?
|
|
50
|
-
true
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def supports_multiline_strings?
|
|
54
|
-
true
|
|
55
|
-
end
|
|
56
|
-
|
|
57
36
|
# Subclasses should override this to specify their library name
|
|
58
37
|
def library_require_name
|
|
59
38
|
raise NotImplementedError, 'Subclasses must implement #library_require_name'
|
|
@@ -31,22 +31,6 @@ module Serialbench
|
|
|
31
31
|
require 'toml-rb'
|
|
32
32
|
TomlRB.dump(object)
|
|
33
33
|
end
|
|
34
|
-
|
|
35
|
-
def supports_comments?
|
|
36
|
-
false
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def supports_arrays_of_tables?
|
|
40
|
-
true
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def supports_inline_tables?
|
|
44
|
-
true
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def supports_multiline_strings?
|
|
48
|
-
true
|
|
49
|
-
end
|
|
50
34
|
end
|
|
51
35
|
end
|
|
52
36
|
end
|