serialbench 0.1.3 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/scripts/push-to-data.sh +65 -0
- data/.github/workflows/benchmark.yml +134 -168
- data/.github/workflows/release.yml +68 -13
- data/Gemfile +2 -0
- data/README.adoc +5 -0
- data/config/benchmarks/full-json.yml +25 -0
- data/config/benchmarks/full-toml.yml +25 -0
- data/config/benchmarks/full-xml.yml +26 -0
- data/config/benchmarks/full-yaml.yml +25 -0
- data/config/benchmarks/full.yml +9 -4
- data/lib/serialbench/benchmark_runner.rb +20 -23
- data/lib/serialbench/cli/benchmark_cli.rb +1 -1
- data/lib/serialbench/cli/resultset_cli.rb +40 -0
- data/lib/serialbench/cli.rb +1 -8
- data/lib/serialbench/models/benchmark_result.rb +2 -0
- data/lib/serialbench/models/platform.rb +5 -2
- data/lib/serialbench/serializers/base_serializer.rb +14 -2
- data/lib/serialbench/serializers/json/rapidjson_serializer.rb +0 -4
- data/lib/serialbench/serializers/xml/base_xml_serializer.rb +6 -5
- data/lib/serialbench/serializers/xml/leptris_serializer.rb +174 -0
- data/lib/serialbench/serializers/xml/libxml_serializer.rb +9 -0
- data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +4 -0
- data/lib/serialbench/serializers/xml/oga_serializer.rb +8 -0
- data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +1 -3
- data/lib/serialbench/serializers/yaml/psych_serializer.rb +0 -4
- data/lib/serialbench/serializers.rb +3 -1
- data/lib/serialbench/site_generator.rb +56 -2
- data/lib/serialbench/version.rb +1 -1
- data/lib/serialbench.rb +1 -1
- metadata +9 -15
- data/lib/serialbench/templates/assets/css/benchmark_report.css +0 -535
- data/lib/serialbench/templates/assets/css/format_based.css +0 -474
- data/lib/serialbench/templates/assets/css/themes.css +0 -589
- data/lib/serialbench/templates/assets/js/chart_helpers.js +0 -411
- data/lib/serialbench/templates/assets/js/dashboard.js +0 -795
- data/lib/serialbench/templates/assets/js/navigation.js +0 -142
- data/lib/serialbench/templates/base.liquid +0 -49
- data/lib/serialbench/templates/format_based.liquid +0 -507
- data/lib/serialbench/templates/partials/chart_section.liquid +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed5cf6538b0a64c26b9d9c0739b943f750f30476aa27a94c5b87aae98c203b55
|
|
4
|
+
data.tar.gz: 3d1e7eb5c8f71c4052014729bd6dbbf4417a68339065a7a934ea1e5a3ef82a3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8bd0e7a6052712f3a49c4656e6aa663cd4db2215c9f9ebc3ac8379b7f258f78e488fdfc46bb52a8e6e9d89cc07ef78fa4fbebe6f0471881b679d40d5ab42284d
|
|
7
|
+
data.tar.gz: 5441d7d92266df86976a78dd4fb68acf8c491147c799b06aa9e1a67ac5bd382dfd27547505e4566483a9657f983bc7bb0ffb5280cc17089de61a8b070fe5677b
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Pushes one format's results.yaml to serialbench/data via the GitHub
|
|
3
|
+
# Contents API (atomic per-file, no merge conflicts from parallel legs).
|
|
4
|
+
# Called after each format's benchmark completes — the site rebuilds
|
|
5
|
+
# incrementally as data arrives.
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
FMT="$1"
|
|
9
|
+
RUBY_VERSION="$2"
|
|
10
|
+
PLATFORM="$3"
|
|
11
|
+
RESULTS_FILE="results/runs/ci-ruby-${RUBY_VERSION}-${PLATFORM}/${FMT}/results.yaml"
|
|
12
|
+
DATA_TOKEN="${DATA_REPO_TOKEN:-}"
|
|
13
|
+
|
|
14
|
+
if [ -z "$DATA_TOKEN" ]; then
|
|
15
|
+
echo "::warning::DATA_REPO_TOKEN not set — skipping data push"
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
if [ ! -f "$RESULTS_FILE" ]; then
|
|
20
|
+
echo "::warning::No results at $RESULTS_FILE — skipping"
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
DATE=$(date -u +%Y-%m-%d)
|
|
25
|
+
TARGET_PATH="runs/${DATE}/${PLATFORM}-ruby-${RUBY_VERSION}.${FMT}.yaml"
|
|
26
|
+
CONTENT=$(base64 < "$RESULTS_FILE")
|
|
27
|
+
|
|
28
|
+
echo "Pushing ${TARGET_PATH} to serialbench/data..."
|
|
29
|
+
|
|
30
|
+
# Try create; if file exists (422), get sha and update
|
|
31
|
+
HTTP_CODE=$(curl -s -o /tmp/data-push-resp.json -w "%{http_code}" -X PUT \
|
|
32
|
+
-H "Authorization: Bearer ${DATA_TOKEN}" \
|
|
33
|
+
-H "Accept: application/vnd.github+json" \
|
|
34
|
+
"https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
|
|
35
|
+
-d "{\"message\": \"${PLATFORM} ruby-${RUBY_VERSION} ${FMT}\", \"content\": \"${CONTENT}\", \"branch\": \"main\"}")
|
|
36
|
+
|
|
37
|
+
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
|
|
38
|
+
echo "Pushed ${TARGET_PATH}"
|
|
39
|
+
elif [ "$HTTP_CODE" = "422" ]; then
|
|
40
|
+
SHA=$(curl -sf \
|
|
41
|
+
-H "Authorization: Bearer ${DATA_TOKEN}" \
|
|
42
|
+
"https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
|
|
43
|
+
| grep -oE '"sha":\s*"[a-f0-9]+"' | head -1 | grep -oE '[a-f0-9]{40}')
|
|
44
|
+
if [ -n "$SHA" ]; then
|
|
45
|
+
curl -sf -X PUT \
|
|
46
|
+
-H "Authorization: Bearer ${DATA_TOKEN}" \
|
|
47
|
+
-H "Accept: application/vnd.github+json" \
|
|
48
|
+
"https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
|
|
49
|
+
-d "{\"message\": \"${PLATFORM} ruby-${RUBY_VERSION} ${FMT} (update)\", \"content\": \"${CONTENT}\", \"sha\": \"${SHA}\", \"branch\": \"main\"}" > /dev/null
|
|
50
|
+
echo "Updated existing ${TARGET_PATH}"
|
|
51
|
+
else
|
|
52
|
+
echo "::warning::422 but couldn't get sha for ${TARGET_PATH}"
|
|
53
|
+
fi
|
|
54
|
+
else
|
|
55
|
+
echo "::warning::Push failed (${HTTP_CODE}): $(cat /tmp/data-push-resp.json | head -c 200)"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Trigger site rebuild (debounced by concurrency group on the .io repo)
|
|
59
|
+
curl -sf -X POST \
|
|
60
|
+
-H "Authorization: Bearer ${DATA_TOKEN}" \
|
|
61
|
+
-H "Accept: application/vnd.github+json" \
|
|
62
|
+
"https://api.github.com/repos/serialbench/serialbench.github.io/dispatches" \
|
|
63
|
+
-d '{"event_type": "data-updated"}' \
|
|
64
|
+
&& echo "Site rebuild triggered" \
|
|
65
|
+
|| echo "::warning::Failed to trigger site rebuild"
|
|
@@ -16,11 +16,9 @@ on:
|
|
|
16
16
|
|
|
17
17
|
permissions:
|
|
18
18
|
contents: read
|
|
19
|
-
pages: write
|
|
20
|
-
id-token: write
|
|
21
19
|
|
|
22
20
|
concurrency:
|
|
23
|
-
group: "
|
|
21
|
+
group: "site-deploy"
|
|
24
22
|
cancel-in-progress: false
|
|
25
23
|
|
|
26
24
|
jobs:
|
|
@@ -33,8 +31,8 @@ jobs:
|
|
|
33
31
|
- name: Set matrix configurations
|
|
34
32
|
id: set-matrix
|
|
35
33
|
run: |
|
|
36
|
-
echo 'ruby-versions=["3.
|
|
37
|
-
echo 'platforms=["ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-
|
|
34
|
+
echo 'ruby-versions=["3.2", "3.3", "3.4", "4.0"]' >> $GITHUB_OUTPUT
|
|
35
|
+
echo 'platforms=["ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-14", "macos-15", "macos-15-intel", "macos-26", "macos-26-intel", "windows-2022", "windows-2025", "windows-11-arm"]' >> $GITHUB_OUTPUT
|
|
38
36
|
|
|
39
37
|
# Cross-platform native benchmarks
|
|
40
38
|
benchmark:
|
|
@@ -46,9 +44,8 @@ jobs:
|
|
|
46
44
|
platform: ${{ fromJson(needs.setup.outputs.platforms) }}
|
|
47
45
|
ruby-version: ${{ fromJson(needs.setup.outputs.ruby-versions) }}
|
|
48
46
|
exclude:
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
ruby-version: "3.1"
|
|
47
|
+
# RubyInstaller ships no arm64 builds for Ruby 3.2/3.3;
|
|
48
|
+
# windows-11-arm runs 3.4.x and 4.x only
|
|
52
49
|
- platform: windows-11-arm
|
|
53
50
|
ruby-version: "3.2"
|
|
54
51
|
- platform: windows-11-arm
|
|
@@ -72,8 +69,9 @@ jobs:
|
|
|
72
69
|
- name: Install vcpkg dependencies (Windows)
|
|
73
70
|
if: startsWith(matrix.platform, 'windows-')
|
|
74
71
|
run: |
|
|
75
|
-
vcpkg install libxml2:${{ steps.windows-arch.outputs.arch }} 2>&1 || true
|
|
72
|
+
vcpkg install libxml2:${{ steps.windows-arch.outputs.arch }} libxslt:${{ steps.windows-arch.outputs.arch }} 2>&1 || true
|
|
76
73
|
vcpkg integrate install 2>&1 || true
|
|
74
|
+
echo "C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/bin" >> $GITHUB_PATH
|
|
77
75
|
shell: bash
|
|
78
76
|
|
|
79
77
|
- name: Configure bundler for libxml2 (Windows)
|
|
@@ -82,6 +80,7 @@ jobs:
|
|
|
82
80
|
mkdir -p .bundle 2>&1 || true
|
|
83
81
|
echo "---" > .bundle/config 2>&1 || true
|
|
84
82
|
echo 'BUNDLE_BUILD__LIBXML___RUBY: "--with-xml2-dir=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }} --with-xml2-include=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/include/libxml2 --with-xml2-lib=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/lib"' >> .bundle/config 2>&1 || true
|
|
83
|
+
echo 'BUNDLE_BUILD__NOKOGIRI: "--use-system-libraries --with-xml2-include=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/include/libxml2 --with-xml2-lib=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/lib --with-xslt-include=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/include/libxslt --with-xslt-lib=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/lib --with-zlib-dir=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}"' >> .bundle/config 2>&1 || true
|
|
85
84
|
shell: bash
|
|
86
85
|
|
|
87
86
|
- name: Set up Ruby ${{ matrix.ruby-version }}
|
|
@@ -90,6 +89,14 @@ jobs:
|
|
|
90
89
|
ruby-version: ${{ matrix.ruby-version }}
|
|
91
90
|
bundler-cache: true
|
|
92
91
|
|
|
92
|
+
- name: Stage vcpkg DLLs beside ruby.exe (Windows)
|
|
93
|
+
if: startsWith(matrix.platform, 'windows-')
|
|
94
|
+
run: |
|
|
95
|
+
RUBY_BIN="$(dirname "$(command -v ruby)")"
|
|
96
|
+
ls "C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/bin/" || true
|
|
97
|
+
cp -f "C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/bin/"*.dll "$RUBY_BIN/" 2>&1 || true
|
|
98
|
+
shell: bash
|
|
99
|
+
|
|
93
100
|
- name: Install system dependencies (Ubuntu)
|
|
94
101
|
if: startsWith(matrix.platform, 'ubuntu-')
|
|
95
102
|
run: |
|
|
@@ -101,25 +108,28 @@ jobs:
|
|
|
101
108
|
run: |
|
|
102
109
|
brew install libxml2 libxslt
|
|
103
110
|
|
|
104
|
-
- name: Debug Ruby platform (Windows only)
|
|
105
|
-
if: startsWith(matrix.platform, 'windows-')
|
|
106
|
-
shell: ruby {0}
|
|
107
|
-
run: |
|
|
108
|
-
puts "=== Ruby Platform Debug Info ==="
|
|
109
|
-
puts "RUBY_PLATFORM: #{RUBY_PLATFORM}"
|
|
110
|
-
puts "Gem.win_platform?: #{Gem.win_platform?}"
|
|
111
|
-
puts "RbConfig::CONFIG['host_os']: #{RbConfig::CONFIG['host_os']}"
|
|
112
|
-
puts "RbConfig::CONFIG['host_cpu']: #{RbConfig::CONFIG['host_cpu']}"
|
|
113
|
-
puts "RbConfig::CONFIG['arch']: #{RbConfig::CONFIG['arch']}"
|
|
114
|
-
puts "================================"
|
|
115
|
-
|
|
116
111
|
- name: Install gems
|
|
117
112
|
run: bundle install
|
|
118
113
|
|
|
119
|
-
- name:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
|
123
133
|
|
|
124
134
|
- name: Create environment config
|
|
125
135
|
run: |
|
|
@@ -134,160 +144,124 @@ jobs:
|
|
|
134
144
|
EOF
|
|
135
145
|
shell: bash
|
|
136
146
|
|
|
137
|
-
|
|
147
|
+
# Each format is an independent checkpoint with its own upload.
|
|
148
|
+
# A failure in one format doesn't prevent the others from uploading.
|
|
149
|
+
- name: Benchmark xml
|
|
150
|
+
continue-on-error: true
|
|
151
|
+
shell: bash
|
|
138
152
|
env:
|
|
139
153
|
GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
|
|
140
154
|
run: |
|
|
141
|
-
bundle exec serialbench environment execute
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
echo "=== Verifying benchmark results ==="
|
|
146
|
-
RESULTS_FILE="results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/results.yaml"
|
|
147
|
-
|
|
148
|
-
echo "📁 Checking file exists..."
|
|
149
|
-
if [ ! -f "$RESULTS_FILE" ]; then
|
|
150
|
-
echo "❌ ERROR: results.yaml not found at $RESULTS_FILE"
|
|
151
|
-
exit 1
|
|
152
|
-
fi
|
|
153
|
-
|
|
154
|
-
echo "📊 Checking file size..."
|
|
155
|
-
SIZE=$(wc -c < "$RESULTS_FILE" | tr -d ' ')
|
|
156
|
-
echo " File size: $SIZE bytes"
|
|
155
|
+
bundle exec serialbench environment execute \
|
|
156
|
+
config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
|
|
157
|
+
config/benchmarks/full-xml.yml \
|
|
158
|
+
"results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml"
|
|
157
159
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
- name: Upload xml
|
|
161
|
+
if: ${{ !cancelled() }}
|
|
162
|
+
uses: actions/upload-artifact@v4
|
|
163
|
+
with:
|
|
164
|
+
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-xml
|
|
165
|
+
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml
|
|
166
|
+
retention-days: 30
|
|
167
|
+
if-no-files-found: warn
|
|
165
168
|
|
|
166
|
-
|
|
169
|
+
- name: Push xml to data repo
|
|
170
|
+
if: ${{ !cancelled() }}
|
|
171
|
+
continue-on-error: true
|
|
172
|
+
env:
|
|
173
|
+
DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
|
|
174
|
+
run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
167
175
|
shell: bash
|
|
168
176
|
|
|
169
|
-
- name:
|
|
177
|
+
- name: Benchmark json
|
|
178
|
+
continue-on-error: true
|
|
179
|
+
shell: bash
|
|
180
|
+
env:
|
|
181
|
+
GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
|
|
170
182
|
run: |
|
|
171
|
-
bundle exec serialbench
|
|
183
|
+
bundle exec serialbench environment execute \
|
|
184
|
+
config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
|
|
185
|
+
config/benchmarks/full-json.yml \
|
|
186
|
+
"results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/json"
|
|
172
187
|
|
|
173
|
-
- name: Upload
|
|
188
|
+
- name: Upload json
|
|
189
|
+
if: ${{ !cancelled() }}
|
|
174
190
|
uses: actions/upload-artifact@v4
|
|
175
191
|
with:
|
|
176
|
-
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}
|
|
177
|
-
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}
|
|
192
|
+
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-json
|
|
193
|
+
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/json
|
|
178
194
|
retention-days: 30
|
|
195
|
+
if-no-files-found: warn
|
|
179
196
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
url: ${{ steps.deployment.outputs.page_url }}
|
|
188
|
-
|
|
189
|
-
steps:
|
|
190
|
-
- name: Checkout repository
|
|
191
|
-
uses: actions/checkout@v4
|
|
192
|
-
|
|
193
|
-
- name: Set up Ruby
|
|
194
|
-
uses: ruby/setup-ruby@v1
|
|
195
|
-
with:
|
|
196
|
-
ruby-version: '3.3'
|
|
197
|
-
bundler-cache: true
|
|
197
|
+
- name: Push json to data repo
|
|
198
|
+
if: ${{ !cancelled() }}
|
|
199
|
+
continue-on-error: true
|
|
200
|
+
env:
|
|
201
|
+
DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
|
|
202
|
+
run: .github/scripts/push-to-data.sh json ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
203
|
+
shell: bash
|
|
198
204
|
|
|
199
|
-
- name:
|
|
205
|
+
- name: Benchmark yaml
|
|
206
|
+
continue-on-error: true
|
|
207
|
+
shell: bash
|
|
208
|
+
env:
|
|
209
|
+
GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
|
|
200
210
|
run: |
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
run: bundle install
|
|
211
|
+
bundle exec serialbench environment execute \
|
|
212
|
+
config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
|
|
213
|
+
config/benchmarks/full-yaml.yml \
|
|
214
|
+
"results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/yaml"
|
|
206
215
|
|
|
207
|
-
- name:
|
|
208
|
-
|
|
216
|
+
- name: Upload yaml
|
|
217
|
+
if: ${{ !cancelled() }}
|
|
218
|
+
uses: actions/upload-artifact@v4
|
|
209
219
|
with:
|
|
210
|
-
|
|
211
|
-
path:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
run: |
|
|
215
|
-
echo "=== Artifacts directory structure ==="
|
|
216
|
-
ls -la artifacts/
|
|
217
|
-
echo ""
|
|
218
|
-
echo "=== Searching for results.yaml files ==="
|
|
219
|
-
find artifacts/ -name "results.yaml" -type f
|
|
220
|
-
echo ""
|
|
221
|
-
echo "=== Directory tree (first 3 levels) ==="
|
|
222
|
-
find artifacts/ -maxdepth 3 -type d | sort
|
|
223
|
-
|
|
224
|
-
- name: Create resultset
|
|
225
|
-
run: |
|
|
226
|
-
mkdir -p results/sets
|
|
227
|
-
bundle exec serialbench resultset create weekly-benchmark results/sets/weekly-benchmark
|
|
228
|
-
|
|
229
|
-
- name: Add all results to resultset
|
|
230
|
-
run: |
|
|
231
|
-
bundle exec serialbench resultset add-result results/sets/weekly-benchmark artifacts/benchmark-results-*/
|
|
220
|
+
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-yaml
|
|
221
|
+
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/yaml
|
|
222
|
+
retention-days: 30
|
|
223
|
+
if-no-files-found: warn
|
|
232
224
|
|
|
233
|
-
- name:
|
|
234
|
-
|
|
235
|
-
|
|
225
|
+
- name: Push yaml to data repo
|
|
226
|
+
if: ${{ !cancelled() }}
|
|
227
|
+
continue-on-error: true
|
|
228
|
+
env:
|
|
229
|
+
DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
|
|
230
|
+
run: .github/scripts/push-to-data.sh yaml ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
231
|
+
shell: bash
|
|
236
232
|
|
|
237
|
-
- name:
|
|
233
|
+
- name: Benchmark toml
|
|
234
|
+
continue-on-error: true
|
|
235
|
+
shell: bash
|
|
236
|
+
env:
|
|
237
|
+
GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
|
|
238
238
|
run: |
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
This site contains automated benchmark results for Ruby serialization libraries.
|
|
239
|
+
bundle exec serialbench environment execute \
|
|
240
|
+
config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
|
|
241
|
+
config/benchmarks/full-toml.yml \
|
|
242
|
+
"results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/toml"
|
|
244
243
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
- **JSON**: JSON, Oj, RapidJSON, YAJL
|
|
249
|
-
- **YAML**: Psych
|
|
250
|
-
- **TOML**: TOML-RB, Tomlib, tomlrb
|
|
251
|
-
|
|
252
|
-
## Platforms Tested
|
|
253
|
-
|
|
254
|
-
- Ubuntu Latest (Linux x86_64)
|
|
255
|
-
- Ubuntu 24.04 (Linux ARM64)
|
|
256
|
-
- Ubuntu 22.04 (Linux ARM64)
|
|
257
|
-
- macOS 13 (Intel x86_64)
|
|
258
|
-
- macOS 15 Intel (Intel x86_64)
|
|
259
|
-
- macOS 14 (Apple Silicon ARM64)
|
|
260
|
-
- macOS 15 (Apple Silicon ARM64)
|
|
261
|
-
|
|
262
|
-
## Ruby Versions
|
|
263
|
-
|
|
264
|
-
- Ruby 3.1, 3.2, 3.3, 3.4
|
|
265
|
-
|
|
266
|
-
## View Results
|
|
267
|
-
|
|
268
|
-
Open [index.html](./index.html) to view the interactive dashboard.
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
*Last updated: $(date -u +"%Y-%m-%d %H:%M:%S UTC")*
|
|
273
|
-
EOF
|
|
274
|
-
|
|
275
|
-
- name: Setup Pages
|
|
276
|
-
uses: actions/configure-pages@v4
|
|
277
|
-
|
|
278
|
-
- name: Upload to GitHub Pages
|
|
279
|
-
uses: actions/upload-pages-artifact@v3
|
|
244
|
+
- name: Upload toml
|
|
245
|
+
if: ${{ !cancelled() }}
|
|
246
|
+
uses: actions/upload-artifact@v4
|
|
280
247
|
with:
|
|
281
|
-
|
|
248
|
+
name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-toml
|
|
249
|
+
path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/toml
|
|
250
|
+
retention-days: 30
|
|
251
|
+
if-no-files-found: warn
|
|
282
252
|
|
|
283
|
-
- name:
|
|
284
|
-
|
|
285
|
-
|
|
253
|
+
- name: Push toml to data repo
|
|
254
|
+
if: ${{ !cancelled() }}
|
|
255
|
+
continue-on-error: true
|
|
256
|
+
env:
|
|
257
|
+
DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
|
|
258
|
+
run: .github/scripts/push-to-data.sh toml ${{ matrix.ruby-version }} ${{ matrix.platform }}
|
|
259
|
+
shell: bash
|
|
286
260
|
|
|
287
261
|
# Summary job
|
|
288
262
|
summary:
|
|
289
263
|
runs-on: ubuntu-latest
|
|
290
|
-
needs: [setup, benchmark
|
|
264
|
+
needs: [setup, benchmark]
|
|
291
265
|
if: always()
|
|
292
266
|
steps:
|
|
293
267
|
- name: Generate workflow summary
|
|
@@ -295,27 +269,19 @@ jobs:
|
|
|
295
269
|
echo "## Weekly Benchmark Summary" >> $GITHUB_STEP_SUMMARY
|
|
296
270
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
297
271
|
echo "**Benchmark Status**: ${{ needs.benchmark.result }}" >> $GITHUB_STEP_SUMMARY
|
|
298
|
-
echo "**
|
|
272
|
+
echo "**Incremental pushes**: each format pushes to data repo on completion" >> $GITHUB_STEP_SUMMARY
|
|
299
273
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
300
274
|
echo "### Platforms Tested" >> $GITHUB_STEP_SUMMARY
|
|
301
|
-
echo "- Ubuntu
|
|
302
|
-
echo "- Ubuntu
|
|
303
|
-
echo "-
|
|
304
|
-
echo "-
|
|
305
|
-
echo "- macOS 15 Intel (Intel x86_64)" >> $GITHUB_STEP_SUMMARY
|
|
306
|
-
echo "- macOS 14 (Apple Silicon ARM64)" >> $GITHUB_STEP_SUMMARY
|
|
307
|
-
echo "- macOS 15 (Apple Silicon ARM64)" >> $GITHUB_STEP_SUMMARY
|
|
275
|
+
echo "- Ubuntu 24.04 (x86_64 + ARM64)" >> $GITHUB_STEP_SUMMARY
|
|
276
|
+
echo "- Ubuntu 22.04 (x86_64 + ARM64)" >> $GITHUB_STEP_SUMMARY
|
|
277
|
+
echo "- macOS 14, 15, 26 (ARM64 + Intel)" >> $GITHUB_STEP_SUMMARY
|
|
278
|
+
echo "- Windows 2022, 2025, 11-ARM" >> $GITHUB_STEP_SUMMARY
|
|
308
279
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
309
280
|
echo "### Ruby Versions" >> $GITHUB_STEP_SUMMARY
|
|
310
|
-
echo "- Ruby 3.
|
|
311
|
-
echo "" >> $GITHUB_STEP_SUMMARY
|
|
312
|
-
echo "### Serialization Libraries" >> $GITHUB_STEP_SUMMARY
|
|
313
|
-
echo "- **XML**: REXML, Ox, Nokogiri, Oga, LibXML" >> $GITHUB_STEP_SUMMARY
|
|
314
|
-
echo "- **JSON**: JSON, Oj, RapidJSON, YAJL" >> $GITHUB_STEP_SUMMARY
|
|
315
|
-
echo "- **YAML**: Psych" >> $GITHUB_STEP_SUMMARY
|
|
316
|
-
echo "- **TOML**: TOML-RB, Tomlib, tomlrb" >> $GITHUB_STEP_SUMMARY
|
|
281
|
+
echo "- Ruby 3.2, 3.3, 3.4, 4.0" >> $GITHUB_STEP_SUMMARY
|
|
317
282
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
318
283
|
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
|
|
319
284
|
echo "### Results" >> $GITHUB_STEP_SUMMARY
|
|
320
|
-
echo "📊 [View
|
|
285
|
+
echo "📊 [View Dashboard](https://serialbench.github.io/serialbench/)" >> $GITHUB_STEP_SUMMARY
|
|
286
|
+
echo "📦 [Raw Data](https://github.com/serialbench/data)" >> $GITHUB_STEP_SUMMARY
|
|
321
287
|
fi
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# Auto-generated by Cimas: Do not edit it manually!
|
|
2
|
-
# See https://github.com/metanorma/cimas
|
|
3
1
|
name: release
|
|
4
2
|
|
|
5
3
|
on:
|
|
@@ -7,19 +5,76 @@ on:
|
|
|
7
5
|
inputs:
|
|
8
6
|
next_version:
|
|
9
7
|
description: |
|
|
10
|
-
Next release version. Possible values: x.y.z, major, minor, patch
|
|
11
|
-
|
|
8
|
+
Next release version. Possible values: x.y.z, major, minor, patch
|
|
9
|
+
(or pre|rc|etc).
|
|
12
10
|
required: true
|
|
13
|
-
default: '
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
default: 'minor'
|
|
12
|
+
push:
|
|
13
|
+
tags: ['v*']
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
id-token: write
|
|
16
18
|
|
|
17
19
|
jobs:
|
|
18
20
|
release:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
ruby-version: '3.4'
|
|
28
|
+
bundler-cache: true
|
|
29
|
+
|
|
30
|
+
- name: Determine version
|
|
31
|
+
id: version
|
|
32
|
+
run: |
|
|
33
|
+
INPUT="${{ github.event.inputs.next_version }}"
|
|
34
|
+
if [ -z "$INPUT" ]; then
|
|
35
|
+
INPUT="${GITHUB_REF#refs/tags/v}"
|
|
36
|
+
echo "version=${INPUT}" >> "$GITHUB_OUTPUT"
|
|
37
|
+
elif echo "$INPUT" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
|
|
38
|
+
echo "version=${INPUT}" >> "$GITHUB_OUTPUT"
|
|
39
|
+
else
|
|
40
|
+
CURRENT=$(ruby -e "print Gem::Specification.load('serialbench.gemspec').version.to_s")
|
|
41
|
+
case "${INPUT}" in
|
|
42
|
+
major) NEW=$(echo "$CURRENT" | awk -F. '{print $1+1".0.0"}') ;;
|
|
43
|
+
minor) NEW=$(echo "$CURRENT" | awk -F. '{print $1"."$2+1".0"}') ;;
|
|
44
|
+
patch) NEW=$(echo "$CURRENT" | awk -F. '{print $1"."$2"."$3+1}') ;;
|
|
45
|
+
*) NEW="${INPUT}" ;;
|
|
46
|
+
esac
|
|
47
|
+
echo "version=${NEW}" >> "$GITHUB_OUTPUT"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
- name: Update version
|
|
51
|
+
run: |
|
|
52
|
+
VERSION=${{ steps.version.outputs.version }}
|
|
53
|
+
sed -i.bak "s/VERSION = .*/VERSION = '${VERSION}'/" lib/serialbench/version.rb
|
|
54
|
+
rm -f lib/serialbench/version.rb.bak
|
|
55
|
+
git config user.name "release-bot"
|
|
56
|
+
git config user.email "release-bot@users.noreply.github.com"
|
|
57
|
+
git add lib/serialbench/version.rb
|
|
58
|
+
git commit -m "Bump serialbench to ${VERSION}" || exit 0
|
|
59
|
+
git push origin HEAD:main
|
|
60
|
+
|
|
61
|
+
- name: Tag
|
|
62
|
+
run: |
|
|
63
|
+
VERSION=${{ steps.version.outputs.version }}
|
|
64
|
+
git tag "v${VERSION}" 2>/dev/null || true
|
|
65
|
+
git push origin "v${VERSION}" 2>/dev/null || true
|
|
66
|
+
|
|
67
|
+
- name: Build gem
|
|
68
|
+
run: gem build serialbench.gemspec
|
|
69
|
+
|
|
70
|
+
- name: Push to RubyGems
|
|
71
|
+
run: gem push serialbench-*.gem
|
|
72
|
+
env:
|
|
73
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
25
74
|
|
|
75
|
+
- name: Create GitHub Release
|
|
76
|
+
run: |
|
|
77
|
+
VERSION=${{ steps.version.outputs.version }}
|
|
78
|
+
gh release create "v${VERSION}" --title "serialbench ${VERSION}" --generate-notes 2>/dev/null || true
|
|
79
|
+
env:
|
|
80
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
data/Gemfile
CHANGED
|
@@ -12,6 +12,8 @@ unless Gem.win_platform? && RUBY_PLATFORM.include?('aarch64')
|
|
|
12
12
|
gem 'libxml-ruby'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
gem 'leptris', '1.9.0' # pin to latest git tag; newer gems expect APIs not in v1.9.0 source builds # Needs the libleptris shared library (LEPTRIS_LIB_PATH or system install)
|
|
16
|
+
gem 'benchmark' # Removed from stdlib in Ruby 4.0
|
|
15
17
|
gem 'base64' # Required for Ruby 3.4+
|
|
16
18
|
gem 'lutaml-model', '~> 0.7'
|
|
17
19
|
gem 'octokit'
|
data/README.adoc
CHANGED
|
@@ -41,6 +41,11 @@ Serialbench is a comprehensive benchmarking suite that evaluates the performance
|
|
|
41
41
|
| v3.4
|
|
42
42
|
| Pure Ruby XML parser with XPath support
|
|
43
43
|
|
|
44
|
+
| XML
|
|
45
|
+
| https://github.com/leptris/leptris-ruby[Leptris]
|
|
46
|
+
| v1.1.0
|
|
47
|
+
| FFI binding to libleptris (pure-C XML 1.0, XPath 1.0, SAX)
|
|
48
|
+
|
|
44
49
|
| XML
|
|
45
50
|
| https://github.com/ruby/rexml[REXML]
|
|
46
51
|
| v3.4.1
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Per-format split of full.yml: each format runs in its own process so
|
|
2
|
+
# memory profiling of large documents cannot compound across formats
|
|
3
|
+
# (windows runners OOMed with all four formats in one process).
|
|
4
|
+
name: full-json
|
|
5
|
+
|
|
6
|
+
data_sizes:
|
|
7
|
+
- small
|
|
8
|
+
- medium
|
|
9
|
+
- large
|
|
10
|
+
|
|
11
|
+
formats:
|
|
12
|
+
- json
|
|
13
|
+
|
|
14
|
+
iterations:
|
|
15
|
+
small: 10
|
|
16
|
+
medium: 3
|
|
17
|
+
large: 1
|
|
18
|
+
|
|
19
|
+
operations:
|
|
20
|
+
- parse
|
|
21
|
+
- generate
|
|
22
|
+
- streaming
|
|
23
|
+
- memory
|
|
24
|
+
|
|
25
|
+
warmup: 2
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Per-format split of full.yml: each format runs in its own process so
|
|
2
|
+
# memory profiling of large documents cannot compound across formats
|
|
3
|
+
# (windows runners OOMed with all four formats in one process).
|
|
4
|
+
name: full-toml
|
|
5
|
+
|
|
6
|
+
data_sizes:
|
|
7
|
+
- small
|
|
8
|
+
- medium
|
|
9
|
+
- large
|
|
10
|
+
|
|
11
|
+
formats:
|
|
12
|
+
- toml
|
|
13
|
+
|
|
14
|
+
iterations:
|
|
15
|
+
small: 10
|
|
16
|
+
medium: 3
|
|
17
|
+
large: 1
|
|
18
|
+
|
|
19
|
+
operations:
|
|
20
|
+
- parse
|
|
21
|
+
- generate
|
|
22
|
+
- streaming
|
|
23
|
+
- memory
|
|
24
|
+
|
|
25
|
+
warmup: 2
|