serialbench 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/scripts/push-to-data.sh +1 -1
- data/.github/workflows/benchmark.yml +31 -30
- data/CONTEXT.md +11 -0
- data/docs/adr/0001-three-repo-split.md +9 -0
- data/docs/adr/0002-runners-stay.md +9 -0
- data/docs/adr/0003-capability-set.md +9 -0
- data/docs/adr/0004-explicit-workflow-steps.md +9 -0
- data/docs/adr/0005-site-loader-stays-flat.md +9 -0
- data/docs/adr/0006-operations-vocabulary.md +9 -0
- data/lib/serialbench/benchmark_runner.rb +5 -0
- data/lib/serialbench/serializers.rb +1 -1
- data/lib/serialbench/version.rb +1 -1
- data/lib/serialbench.rb +0 -1
- metadata +8 -3
- data/lib/serialbench/config_manager.rb +0 -129
- data/lib/serialbench/memory_profiler.rb +0 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 55b58686ee445c84cbbf69588022d932a56c7014255567c19d3bc44c2ddbad53
|
|
4
|
+
data.tar.gz: 0353b87e4e5d5690a706e2ef3b2e3d96f85166092b098893c13b9024b56acf4e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fdf9e8086fa5e7960151717340df5f131679af2389bf4126801f9a2ab777fed04f3eba511d108e2a4fe2d3f9e47c723970a22911b20880a162d93fdf85f7ace5
|
|
7
|
+
data.tar.gz: 665f581b8491ce518a0602f76dfc7227ae51c14f343bbf650c6ee5e4b735b3d64676d4af3fd2b6e10d9eb16209ca9ec412763072183d1101cf6e63c40088a83d
|
|
@@ -23,7 +23,7 @@ fi
|
|
|
23
23
|
|
|
24
24
|
DATE=$(date -u +%Y-%m-%d)
|
|
25
25
|
TARGET_PATH="runs/${DATE}/${PLATFORM}-ruby-${RUBY_VERSION}.${FMT}.yaml"
|
|
26
|
-
CONTENT=$(base64 < "$RESULTS_FILE")
|
|
26
|
+
CONTENT=$(base64 < "$RESULTS_FILE" | tr -d '\r\n')
|
|
27
27
|
|
|
28
28
|
echo "Pushing ${TARGET_PATH} to serialbench/data..."
|
|
29
29
|
|
|
@@ -120,36 +120,6 @@ jobs:
|
|
|
120
120
|
EOF
|
|
121
121
|
shell: bash
|
|
122
122
|
|
|
123
|
-
# Each format is an independent checkpoint with its own upload.
|
|
124
|
-
# A failure in one format doesn't prevent the others from uploading.
|
|
125
|
-
- name: Benchmark xml
|
|
126
|
-
continue-on-error: true
|
|
127
|
-
shell: bash
|
|
128
|
-
env:
|
|
129
|
-
GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
|
|
130
|
-
run: |
|
|
131
|
-
bundle exec serialbench environment execute \
|
|
132
|
-
config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
|
|
133
|
-
config/benchmarks/full-xml.yml \
|
|
134
|
-
"results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml"
|
|
135
|
-
|
|
136
|
-
- name: Upload xml
|
|
137
|
-
if: ${{ !cancelled() }}
|
|
138
|
-
uses: actions/upload-artifact@v4
|
|
139
|
-
with:
|
|
140
|
-
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-xml
|
|
141
|
-
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml
|
|
142
|
-
retention-days: 30
|
|
143
|
-
if-no-files-found: warn
|
|
144
|
-
|
|
145
|
-
- name: Push xml to data repo
|
|
146
|
-
if: ${{ !cancelled() }}
|
|
147
|
-
continue-on-error: true
|
|
148
|
-
env:
|
|
149
|
-
DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
|
|
150
|
-
run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
151
|
-
shell: bash
|
|
152
|
-
|
|
153
123
|
- name: Benchmark json
|
|
154
124
|
continue-on-error: true
|
|
155
125
|
shell: bash
|
|
@@ -234,6 +204,37 @@ jobs:
|
|
|
234
204
|
run: .github/scripts/push-to-data.sh toml ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
235
205
|
shell: bash
|
|
236
206
|
|
|
207
|
+
# Each format is an independent checkpoint with its own upload.
|
|
208
|
+
# A failure in one format doesn't prevent the others from uploading.
|
|
209
|
+
- name: Benchmark xml
|
|
210
|
+
continue-on-error: true
|
|
211
|
+
shell: bash
|
|
212
|
+
env:
|
|
213
|
+
GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
|
|
214
|
+
run: |
|
|
215
|
+
bundle exec serialbench environment execute \
|
|
216
|
+
config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
|
|
217
|
+
config/benchmarks/full-xml.yml \
|
|
218
|
+
"results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml"
|
|
219
|
+
|
|
220
|
+
- name: Upload xml
|
|
221
|
+
if: ${{ !cancelled() }}
|
|
222
|
+
uses: actions/upload-artifact@v4
|
|
223
|
+
with:
|
|
224
|
+
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-xml
|
|
225
|
+
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml
|
|
226
|
+
retention-days: 30
|
|
227
|
+
if-no-files-found: warn
|
|
228
|
+
|
|
229
|
+
- name: Push xml to data repo
|
|
230
|
+
if: ${{ !cancelled() }}
|
|
231
|
+
continue-on-error: true
|
|
232
|
+
env:
|
|
233
|
+
DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
|
|
234
|
+
run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
235
|
+
shell: bash
|
|
236
|
+
|
|
237
|
+
|
|
237
238
|
# Summary job
|
|
238
239
|
summary:
|
|
239
240
|
runs-on: ubuntu-latest
|
data/CONTEXT.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Serialbench domain glossary
|
|
2
|
+
|
|
3
|
+
- **Adapter** (a.k.a. serializer): one Ruby serialization library under measurement (nokogiri, leptris, oj, psych, toml-rb…). Registered per format in `Serializers::Serializers::REGISTER`. Its interface is the **capability set** (`capabilities` → `Set<Symbol>`); the `features` hash export derives from it.
|
|
4
|
+
- **Format**: xml, json, yaml, toml. One adapter belongs to exactly one format; one format has several adapters.
|
|
5
|
+
- **Operation**: one measured workload — `parsing`, `generation`, `xpath`, `streaming` (the `OPERATIONS` table in `BenchmarkRunner`), plus `memory` (profiled separately). Config `operations:` uses exactly these names; absent = run all; unknown name = error.
|
|
6
|
+
- **Result Leg**: one platform × ruby × format benchmark execution (one process, one config file). Produces one `results.yaml`.
|
|
7
|
+
- **Data Run**: one dated directory in the data repo (`runs/YYYY-MM-DD/`), holding one YAML file per environment × format. Append-only; the site's aggregator takes the latest run's data per environment.
|
|
8
|
+
- **Environment**: where a leg executes — `local`, `docker`, or `asdf` (`kind` in the environment config). Dispatched through `Runners.for`.
|
|
9
|
+
- **Environment key**: `{platform}-ruby-{version}` (e.g. `macos-26-ruby-3.4`) — the site's identity for a platform×ruby pair.
|
|
10
|
+
- **Capability**: a symbol in an adapter's capability set (`:xpath`, `:sax`, `:stax`, `:generate`, `:namespaces`…). Benchmarks filter adapters by capability; the site renders them as the capability strip.
|
|
11
|
+
- **Fixture**: the generated test document for a format × size (`small`/`medium`/`large`), built by `Serialbench::TestData`. `test_data/{size}.{format}` files override the generated one.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# ADR-0001: Three-repo split with incremental per-format pushes
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-28
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
The monolith coupled benchmark code, result storage, and site rendering; every publish was a batch job whose failure lost everything.
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
Three repos: `serialbench/serialbench` (gem), `serialbench/data` (append-only YAML runs), `serialbench/serialbench.github.io` (Astro site). Each Result Leg pushes its file to data via the Contents API immediately and triggers a site rebuild; legs are `continue-on-error` so one eviction never blocks the others.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# ADR-0002: Docker and ASDF runners stay
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-28
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
An architecture round deleted the docker/asdf runners as "unused by CI" (only LocalRunner executes in GitHub Actions).
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
Restore and keep them. The owner's requirement: every platform remains benchmarkable through the gem, not just what current CI exercises. Round 4 then repaired the asdf dispatch so the runner is actually reachable (`Runners.for`). Do not re-suggest deleting runners.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# ADR-0003: The capability set is the single adapter interface
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-29
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
Adapters declared capabilities through 49 individual `supports_X?` predicates, a parallel `features` hash, and (after a partial migration) a `capabilities` Set — three interfaces that could and did contradict (nokogiri's features denied streaming it has; rexml declared xpath without implementing `xpath_query`).
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
One source of truth: `capabilities` returns a `Set<Symbol>`; adapters override with `super | Set.new(...)`; the per-format `features` export derives from it; benchmark selection filters via `supports?`. New capability = one symbol. Do not reintroduce per-capability predicate methods.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# ADR-0004: Benchmark workflow keeps 12 explicit format steps
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-30
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
benchmark.yml repeats a benchmark/upload/push trio per format; a composite action could collapse 12 steps to 4.
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
Decline. `continue-on-error` is a caller-side property a composite cannot carry; the independent-checkpoint semantics would need re-implementation; each explicit step is a grep-able checkpoint during incident triage; the pipeline had a fragile week and the duplication is the price of the isolation property. Revisit only if a fifth format arrives.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# ADR-0005: Site loader stays a flat store
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-29 (reaffirmed 2026-08-30)
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
The site's `loadBenchmarks` returns a flat `BenchmarkStore` that components re-shape; a domain-query loader (leaderboard()/availability()/trend()) was proposed twice.
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
Defer. After the redesign the data layer is small, single-purpose modules (parser/aggregator/trend/versions, 18 tests) and no consumer friction has appeared. Revisit when a second dashboard view forces its own query shape.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# ADR-0006: One operations vocabulary
|
|
2
|
+
|
|
3
|
+
Date: 2026-08-29
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
Benchmark configs declared `parse`/`generate`; the runner's OPERATIONS table used `parsing`/`generation`; `xpath` was in production configs but not the model's legal values; the config's `operations:` list was never read.
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
The OPERATIONS keys plus `memory` are the only legal names, end to end (config values, model validation, runner dispatch). Absent key = run everything; unknown name = `ArgumentError` with guidance. lutaml-model caveat: `default:` on a collection merges into deserialized values, so the everything-default lives in the runner, not the model.
|
|
@@ -135,6 +135,11 @@ module Serialbench
|
|
|
135
135
|
results << result if result
|
|
136
136
|
rescue StandardError => e
|
|
137
137
|
puts " #{format}/#{serializer.name}: ERROR - #{e.message}"
|
|
138
|
+
ensure
|
|
139
|
+
# Free the previous adapter's documents before the next one
|
|
140
|
+
# parses + profiles; without this, six adapters' trees coexist
|
|
141
|
+
# and windows runners OOM during the xml memory pass.
|
|
142
|
+
GC.start
|
|
138
143
|
end
|
|
139
144
|
end
|
|
140
145
|
end
|
|
@@ -75,7 +75,7 @@ module Serialbench
|
|
|
75
75
|
name: serializer_singleton.name,
|
|
76
76
|
format: serializer_singleton.format.to_s,
|
|
77
77
|
version: serializer_singleton.version,
|
|
78
|
-
features: serializer_singleton.features
|
|
78
|
+
features: serializer_singleton.features.transform_keys(&:to_s)
|
|
79
79
|
)
|
|
80
80
|
end
|
|
81
81
|
|
data/lib/serialbench/version.rb
CHANGED
data/lib/serialbench.rb
CHANGED
|
@@ -4,7 +4,6 @@ require_relative 'serialbench/version'
|
|
|
4
4
|
require_relative 'serialbench/serializers'
|
|
5
5
|
require_relative 'serialbench/benchmark_runner'
|
|
6
6
|
require_relative 'serialbench/cli'
|
|
7
|
-
require_relative 'serialbench/memory_profiler'
|
|
8
7
|
require_relative 'serialbench/models'
|
|
9
8
|
|
|
10
9
|
module Serialbench
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: serialbench
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -264,6 +264,7 @@ files:
|
|
|
264
264
|
- ".rspec"
|
|
265
265
|
- ".rubocop.yml"
|
|
266
266
|
- ".rubocop_todo.yml"
|
|
267
|
+
- CONTEXT.md
|
|
267
268
|
- Gemfile
|
|
268
269
|
- README.adoc
|
|
269
270
|
- Rakefile
|
|
@@ -289,6 +290,12 @@ files:
|
|
|
289
290
|
- docs/WEBSITE_COMPLETION_PLAN.md
|
|
290
291
|
- docs/WINDOWS_LIBXML_FIX.md
|
|
291
292
|
- docs/WINDOWS_SETUP.md
|
|
293
|
+
- docs/adr/0001-three-repo-split.md
|
|
294
|
+
- docs/adr/0002-runners-stay.md
|
|
295
|
+
- docs/adr/0003-capability-set.md
|
|
296
|
+
- docs/adr/0004-explicit-workflow-steps.md
|
|
297
|
+
- docs/adr/0005-site-loader-stays-flat.md
|
|
298
|
+
- docs/adr/0006-operations-vocabulary.md
|
|
292
299
|
- exe/serialbench
|
|
293
300
|
- lib/serialbench.rb
|
|
294
301
|
- lib/serialbench/benchmark_runner.rb
|
|
@@ -298,8 +305,6 @@ files:
|
|
|
298
305
|
- lib/serialbench/cli/environment_cli.rb
|
|
299
306
|
- lib/serialbench/cli/ruby_build_cli.rb
|
|
300
307
|
- lib/serialbench/cli/validate_cli.rb
|
|
301
|
-
- lib/serialbench/config_manager.rb
|
|
302
|
-
- lib/serialbench/memory_profiler.rb
|
|
303
308
|
- lib/serialbench/models.rb
|
|
304
309
|
- lib/serialbench/models/benchmark_config.rb
|
|
305
310
|
- lib/serialbench/models/benchmark_result.rb
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'yaml'
|
|
4
|
-
require 'ostruct'
|
|
5
|
-
require_relative 'schema_validator'
|
|
6
|
-
|
|
7
|
-
module Serialbench
|
|
8
|
-
# Manages configuration loading and validation for Serialbench
|
|
9
|
-
class ConfigManager
|
|
10
|
-
class ConfigurationError < StandardError; end
|
|
11
|
-
|
|
12
|
-
SCHEMA_PATH = File.join(__dir__, '../../docs/serialbench_config_schema.yaml')
|
|
13
|
-
|
|
14
|
-
# Load and validate configuration from file
|
|
15
|
-
def self.load_and_validate(config_path)
|
|
16
|
-
new.load_and_validate(config_path)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def initialize
|
|
20
|
-
@validator = SchemaValidator.new
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Load configuration file and validate against schema
|
|
24
|
-
def load_and_validate(config_path)
|
|
25
|
-
raise ConfigurationError, "Configuration file not found: #{config_path}" unless File.exist?(config_path)
|
|
26
|
-
|
|
27
|
-
begin
|
|
28
|
-
config_data = YAML.load_file(config_path)
|
|
29
|
-
rescue Psych::SyntaxError => e
|
|
30
|
-
raise ConfigurationError, "Invalid YAML syntax in #{config_path}: #{e.message}"
|
|
31
|
-
rescue StandardError => e
|
|
32
|
-
raise ConfigurationError, "Error reading configuration file #{config_path}: #{e.message}"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
validate_config(config_data, config_path)
|
|
36
|
-
normalize_config(config_data)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
# Validate configuration against schema
|
|
42
|
-
def validate_config(config_data, _config_path)
|
|
43
|
-
# For now, perform basic validation since we don't have a specific config schema validator
|
|
44
|
-
validate_basic_config(config_data)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Load the configuration schema
|
|
48
|
-
def load_schema
|
|
49
|
-
raise ConfigurationError, "Configuration schema not found: #{SCHEMA_PATH}" unless File.exist?(SCHEMA_PATH)
|
|
50
|
-
|
|
51
|
-
begin
|
|
52
|
-
YAML.load_file(SCHEMA_PATH)
|
|
53
|
-
rescue StandardError => e
|
|
54
|
-
raise ConfigurationError, "Error loading configuration schema: #{e.message}"
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Normalize and convert configuration to structured object
|
|
59
|
-
def normalize_config(config_data)
|
|
60
|
-
config = OpenStruct.new(config_data)
|
|
61
|
-
|
|
62
|
-
# Apply defaults
|
|
63
|
-
config.output_dir ||= 'benchmark-results'
|
|
64
|
-
config.benchmark_config ||= 'config/full.yml'
|
|
65
|
-
config.auto_install = true if config.auto_install.nil?
|
|
66
|
-
|
|
67
|
-
# Validate runtime-specific requirements
|
|
68
|
-
case config.runtime
|
|
69
|
-
when 'docker'
|
|
70
|
-
validate_docker_config(config)
|
|
71
|
-
when 'asdf'
|
|
72
|
-
validate_asdf_config(config)
|
|
73
|
-
else
|
|
74
|
-
raise ConfigurationError, "Unknown runtime: #{config.runtime}"
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
config
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Validate Docker-specific configuration
|
|
81
|
-
def validate_docker_config(config)
|
|
82
|
-
raise ConfigurationError, "Docker runtime requires 'image_variants' to be specified" unless config.image_variants && !config.image_variants.empty?
|
|
83
|
-
|
|
84
|
-
invalid_variants = config.image_variants - %w[slim alpine]
|
|
85
|
-
return if invalid_variants.empty?
|
|
86
|
-
|
|
87
|
-
raise ConfigurationError, "Invalid image variants: #{invalid_variants.join(', ')}. Valid variants: slim, alpine"
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Validate ASDF-specific configuration
|
|
91
|
-
def validate_asdf_config(config)
|
|
92
|
-
# Check if ASDF is available
|
|
93
|
-
raise ConfigurationError, 'ASDF is not installed or not in PATH. Please install ASDF to use asdf runtime.' unless command_available?('asdf')
|
|
94
|
-
|
|
95
|
-
# Validate Ruby version format for ASDF (should include patch version)
|
|
96
|
-
config.ruby_versions.each do |version|
|
|
97
|
-
raise ConfigurationError, "ASDF runtime requires full version numbers (e.g., '3.2.8'), got: #{version}" unless version.match?(/^\d+\.\d+\.\d+$/)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Basic configuration validation
|
|
102
|
-
def validate_basic_config(config_data)
|
|
103
|
-
# Check required fields
|
|
104
|
-
required_fields = %w[runtime ruby_versions output_dir benchmark_config]
|
|
105
|
-
required_fields.each do |field|
|
|
106
|
-
raise ConfigurationError, "Missing required field: #{field}" unless config_data.key?(field)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# Validate runtime
|
|
110
|
-
valid_runtimes = %w[docker asdf]
|
|
111
|
-
unless valid_runtimes.include?(config_data['runtime'])
|
|
112
|
-
raise ConfigurationError,
|
|
113
|
-
"Invalid runtime: #{config_data['runtime']}. Valid runtimes: #{valid_runtimes.join(', ')}"
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Validate ruby_versions is an array
|
|
117
|
-
raise ConfigurationError, 'ruby_versions must be an array' unless config_data['ruby_versions'].is_a?(Array)
|
|
118
|
-
|
|
119
|
-
return unless config_data['ruby_versions'].empty?
|
|
120
|
-
|
|
121
|
-
raise ConfigurationError, 'ruby_versions cannot be empty'
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Check if a command is available in PATH
|
|
125
|
-
def command_available?(command)
|
|
126
|
-
system("which #{command} > /dev/null 2>&1")
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Serialbench
|
|
4
|
-
class MemoryProfiler
|
|
5
|
-
def self.profile(&block)
|
|
6
|
-
return yield unless defined?(::MemoryProfiler)
|
|
7
|
-
|
|
8
|
-
::MemoryProfiler.report(&block)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.available?
|
|
12
|
-
require 'memory_profiler'
|
|
13
|
-
defined?(::MemoryProfiler) ? true : false
|
|
14
|
-
rescue LoadError
|
|
15
|
-
false
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.format_report(report)
|
|
19
|
-
return 'Memory profiling not available' unless report
|
|
20
|
-
|
|
21
|
-
{
|
|
22
|
-
total_allocated: report.total_allocated,
|
|
23
|
-
total_retained: report.total_retained,
|
|
24
|
-
allocated_memory: report.total_allocated_memsize,
|
|
25
|
-
retained_memory: report.total_retained_memsize,
|
|
26
|
-
allocated_objects_by_gem: report.allocated_memory_by_gem,
|
|
27
|
-
retained_objects_by_gem: report.retained_memory_by_gem
|
|
28
|
-
}
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|