expressir 2.1.30 → 2.1.31
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/docs.yml +98 -0
- data/.github/workflows/links.yml +100 -0
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.github/workflows/validate_schemas.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +244 -39
- data/Gemfile +2 -1
- data/README.adoc +621 -54
- data/docs/Gemfile +12 -0
- data/docs/_config.yml +141 -0
- data/docs/_guides/changes/changes-format.adoc +778 -0
- data/docs/_guides/changes/importing-eengine.adoc +898 -0
- data/docs/_guides/changes/index.adoc +396 -0
- data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
- data/docs/_guides/changes/validating-changes.adoc +681 -0
- data/docs/_guides/cli/benchmark-performance.adoc +834 -0
- data/docs/_guides/cli/coverage-analysis.adoc +921 -0
- data/docs/_guides/cli/format-schemas.adoc +547 -0
- data/docs/_guides/cli/index.adoc +8 -0
- data/docs/_guides/cli/managing-changes.adoc +927 -0
- data/docs/_guides/cli/validate-ascii.adoc +645 -0
- data/docs/_guides/cli/validate-schemas.adoc +534 -0
- data/docs/_guides/index.adoc +165 -0
- data/docs/_guides/ler/creating-packages.adoc +664 -0
- data/docs/_guides/ler/index.adoc +305 -0
- data/docs/_guides/ler/loading-packages.adoc +707 -0
- data/docs/_guides/ler/package-formats.adoc +748 -0
- data/docs/_guides/ler/querying-packages.adoc +826 -0
- data/docs/_guides/ler/validating-packages.adoc +750 -0
- data/docs/_guides/liquid/basic-templates.adoc +813 -0
- data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
- data/docs/_guides/liquid/drops-reference.adoc +829 -0
- data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
- data/docs/_guides/liquid/index.adoc +468 -0
- data/docs/_guides/manifests/creating-manifests.adoc +483 -0
- data/docs/_guides/manifests/index.adoc +307 -0
- data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
- data/docs/_guides/manifests/validating-manifests.adoc +713 -0
- data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
- data/docs/_guides/ruby-api/index.adoc +257 -0
- data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
- data/docs/_guides/ruby-api/search-engine.adoc +609 -0
- data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
- data/docs/_pages/data-model.adoc +665 -0
- data/docs/_pages/express-language.adoc +506 -0
- data/docs/_pages/getting-started.adoc +414 -0
- data/docs/_pages/index.adoc +116 -0
- data/docs/_pages/introduction.adoc +256 -0
- data/docs/_pages/ler-packages.adoc +837 -0
- data/docs/_pages/parsers.adoc +683 -0
- data/docs/_pages/schema-manifests.adoc +431 -0
- data/docs/_references/index.adoc +228 -0
- data/docs/_tutorials/creating-ler-package.adoc +735 -0
- data/docs/_tutorials/documentation-coverage.adoc +795 -0
- data/docs/_tutorials/index.adoc +221 -0
- data/docs/_tutorials/liquid-templates.adoc +806 -0
- data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
- data/docs/_tutorials/querying-schemas.adoc +751 -0
- data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
- data/docs/index.adoc +242 -0
- data/docs/lychee.toml +84 -0
- data/examples/demo_ler_usage.sh +86 -0
- data/examples/ler/README.md +111 -0
- data/examples/ler/simple_example.ler +0 -0
- data/examples/ler/simple_schema.exp +33 -0
- data/examples/ler_build.rb +75 -0
- data/examples/ler_cli.rb +79 -0
- data/examples/ler_demo_complete.rb +276 -0
- data/examples/ler_query.rb +91 -0
- data/examples/ler_query_examples.rb +305 -0
- data/examples/ler_stats.rb +81 -0
- data/examples/phase3_demo.rb +159 -0
- data/examples/query_demo_simple.rb +131 -0
- data/expressir.gemspec +2 -0
- data/lib/expressir/cli.rb +12 -4
- data/lib/expressir/commands/manifest.rb +427 -0
- data/lib/expressir/commands/package.rb +1274 -0
- data/lib/expressir/commands/validate.rb +70 -37
- data/lib/expressir/commands/validate_ascii.rb +607 -0
- data/lib/expressir/commands/validate_load.rb +88 -0
- data/lib/expressir/express/formatter.rb +5 -1
- data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
- data/lib/expressir/express/parser.rb +33 -0
- data/lib/expressir/manifest/resolver.rb +213 -0
- data/lib/expressir/manifest/validator.rb +195 -0
- data/lib/expressir/model/declarations/entity.rb +6 -0
- data/lib/expressir/model/dependency_resolver.rb +270 -0
- data/lib/expressir/model/indexes/entity_index.rb +103 -0
- data/lib/expressir/model/indexes/reference_index.rb +148 -0
- data/lib/expressir/model/indexes/type_index.rb +149 -0
- data/lib/expressir/model/interface_validator.rb +384 -0
- data/lib/expressir/model/repository.rb +400 -5
- data/lib/expressir/model/repository_validator.rb +295 -0
- data/lib/expressir/model/search_engine.rb +525 -0
- data/lib/expressir/model.rb +4 -94
- data/lib/expressir/package/builder.rb +200 -0
- data/lib/expressir/package/metadata.rb +81 -0
- data/lib/expressir/package/reader.rb +165 -0
- data/lib/expressir/schema_manifest.rb +11 -1
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +15 -2
- metadata +114 -4
- data/docs/benchmarking.adoc +0 -107
- data/docs/liquid_drops.adoc +0 -1547
|
@@ -0,0 +1,834 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Benchmark Performance
|
|
3
|
+
parent: CLI Guides
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 4
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
== Benchmark Performance
|
|
9
|
+
|
|
10
|
+
=== Purpose
|
|
11
|
+
|
|
12
|
+
The [`benchmark`](../../../lib/expressir/commands/benchmark.rb:1) and [`benchmark-cache`](../../../lib/expressir/commands/benchmark_cache.rb:1) commands measure EXPRESS schema loading performance. These tools help identify performance bottlenecks, compare parsing speeds, and optimize schema processing workflows.
|
|
13
|
+
|
|
14
|
+
=== References
|
|
15
|
+
|
|
16
|
+
* link:../../pages/parsers.html[Parsers Documentation]
|
|
17
|
+
* link:../../tutorials/parsing-your-first-schema.html[Tutorial: Parsing Your First Schema]
|
|
18
|
+
* link:validate-schemas.html[Validate Schemas]
|
|
19
|
+
|
|
20
|
+
=== Concepts
|
|
21
|
+
|
|
22
|
+
Benchmarking:: Measuring the execution time and performance characteristics of operations
|
|
23
|
+
Iterations per second (IPS):: Number of complete operations that can be performed per second
|
|
24
|
+
Cache performance:: Comparing parsing time vs cached loading time
|
|
25
|
+
Objects per second:: Throughput metric for schema elements processed
|
|
26
|
+
Schema manifest:: YAML file listing multiple schemas for batch benchmarking
|
|
27
|
+
|
|
28
|
+
=== Basic Usage
|
|
29
|
+
|
|
30
|
+
==== Benchmark Single File
|
|
31
|
+
|
|
32
|
+
[source,bash]
|
|
33
|
+
----
|
|
34
|
+
# Basic benchmark
|
|
35
|
+
expressir benchmark schema.exp
|
|
36
|
+
----
|
|
37
|
+
|
|
38
|
+
Output:
|
|
39
|
+
[source]
|
|
40
|
+
----
|
|
41
|
+
Express Schema Loading Benchmark
|
|
42
|
+
--------------------------------
|
|
43
|
+
Loading schema.exp: 0.1234s (1250 objects/s)
|
|
44
|
+
Loaded 1 schemas
|
|
45
|
+
----
|
|
46
|
+
|
|
47
|
+
==== Benchmark with Verbose Output
|
|
48
|
+
|
|
49
|
+
[source,bash]
|
|
50
|
+
----
|
|
51
|
+
expressir benchmark schema.exp --verbose
|
|
52
|
+
----
|
|
53
|
+
|
|
54
|
+
Output:
|
|
55
|
+
[source]
|
|
56
|
+
----
|
|
57
|
+
Express Schema Loading Benchmark
|
|
58
|
+
--------------------------------
|
|
59
|
+
Loading schema.exp: 0.1234s (1250 objects/s)
|
|
60
|
+
Loaded 1 schemas
|
|
61
|
+
Objects per second: 1250
|
|
62
|
+
----
|
|
63
|
+
|
|
64
|
+
==== Benchmark with Caching
|
|
65
|
+
|
|
66
|
+
[source,bash]
|
|
67
|
+
----
|
|
68
|
+
expressir benchmark-cache schema.exp
|
|
69
|
+
----
|
|
70
|
+
|
|
71
|
+
Output:
|
|
72
|
+
[source]
|
|
73
|
+
----
|
|
74
|
+
Express Schema Loading Benchmark with Caching
|
|
75
|
+
--------------------------------
|
|
76
|
+
Schema: schema.exp
|
|
77
|
+
Cache: /tmp/expressir_cache20231128.bin
|
|
78
|
+
--------------------------------
|
|
79
|
+
Parsing time: 0.1234s
|
|
80
|
+
Cache write time: 0.0123s
|
|
81
|
+
Cache read time: 0.0045s
|
|
82
|
+
Total objects: 1250
|
|
83
|
+
Objects per second (parsing): 10130.29
|
|
84
|
+
Objects per second (reading): 277777.78
|
|
85
|
+
Loaded 1 schemas
|
|
86
|
+
----
|
|
87
|
+
|
|
88
|
+
=== Command Options
|
|
89
|
+
|
|
90
|
+
==== Benchmark Options
|
|
91
|
+
|
|
92
|
+
[options="header"]
|
|
93
|
+
|===
|
|
94
|
+
| Option | Description | Default
|
|
95
|
+
|
|
96
|
+
| `--ips`
|
|
97
|
+
| Use benchmark-ips for detailed statistics
|
|
98
|
+
| false
|
|
99
|
+
|
|
100
|
+
| `--verbose`
|
|
101
|
+
| Show detailed output including objects/second
|
|
102
|
+
| false
|
|
103
|
+
|
|
104
|
+
| `--save`
|
|
105
|
+
| Save benchmark results to file
|
|
106
|
+
| false
|
|
107
|
+
|
|
108
|
+
| `--format FORMAT`
|
|
109
|
+
| Output format: text, json, or csv
|
|
110
|
+
| text
|
|
111
|
+
|
|
112
|
+
| `--help`, `-h`
|
|
113
|
+
| Display help message
|
|
114
|
+
| -
|
|
115
|
+
|===
|
|
116
|
+
|
|
117
|
+
==== Benchmark-Cache Options
|
|
118
|
+
|
|
119
|
+
[options="header"]
|
|
120
|
+
|===
|
|
121
|
+
| Option | Description | Default
|
|
122
|
+
|
|
123
|
+
| `--cache_path PATH`
|
|
124
|
+
| Custom cache file location
|
|
125
|
+
| Temporary file
|
|
126
|
+
|
|
127
|
+
| `--verbose`
|
|
128
|
+
| Show detailed timing breakdowns
|
|
129
|
+
| false
|
|
130
|
+
|
|
131
|
+
| `--format FORMAT`
|
|
132
|
+
| Output format: text, json, or csv
|
|
133
|
+
| text
|
|
134
|
+
|
|
135
|
+
| `--help`, `-h`
|
|
136
|
+
| Display help message
|
|
137
|
+
| -
|
|
138
|
+
|===
|
|
139
|
+
|
|
140
|
+
=== Benchmark Commands
|
|
141
|
+
|
|
142
|
+
==== Standard Benchmark
|
|
143
|
+
|
|
144
|
+
Measures parsing performance:
|
|
145
|
+
|
|
146
|
+
[source,bash]
|
|
147
|
+
----
|
|
148
|
+
# Single file
|
|
149
|
+
expressir benchmark schema.exp
|
|
150
|
+
|
|
151
|
+
# Multiple files from manifest
|
|
152
|
+
expressir benchmark schemas.yml --verbose
|
|
153
|
+
----
|
|
154
|
+
|
|
155
|
+
==== Benchmark with IPS
|
|
156
|
+
|
|
157
|
+
Uses the `benchmark-ips` gem for more accurate statistics:
|
|
158
|
+
|
|
159
|
+
[source,bash]
|
|
160
|
+
----
|
|
161
|
+
expressir benchmark schema.exp --ips
|
|
162
|
+
----
|
|
163
|
+
|
|
164
|
+
Output:
|
|
165
|
+
[source]
|
|
166
|
+
----
|
|
167
|
+
Warming up --------------------------------------
|
|
168
|
+
Loading schema.exp 1.000 i/100ms
|
|
169
|
+
Calculating -------------------------------------
|
|
170
|
+
Loading schema.exp 8.123 (± 0.0%) i/s - 41.000 in 5.048s
|
|
171
|
+
----
|
|
172
|
+
|
|
173
|
+
==== Benchmark with Caching
|
|
174
|
+
|
|
175
|
+
Compares parsing vs cache loading performance:
|
|
176
|
+
|
|
177
|
+
[source,bash]
|
|
178
|
+
----
|
|
179
|
+
# With automatic temp cache
|
|
180
|
+
expressir benchmark-cache schema.exp --verbose
|
|
181
|
+
|
|
182
|
+
# With custom cache location
|
|
183
|
+
expressir benchmark-cache schema.exp --cache_path /tmp/my_cache.bin
|
|
184
|
+
----
|
|
185
|
+
|
|
186
|
+
=== Output Formats
|
|
187
|
+
|
|
188
|
+
==== Text Format (Default)
|
|
189
|
+
|
|
190
|
+
Human-readable output:
|
|
191
|
+
|
|
192
|
+
[source,bash]
|
|
193
|
+
----
|
|
194
|
+
expressir benchmark schema.exp --verbose
|
|
195
|
+
----
|
|
196
|
+
|
|
197
|
+
[source]
|
|
198
|
+
----
|
|
199
|
+
Express Schema Loading Benchmark
|
|
200
|
+
--------------------------------
|
|
201
|
+
Loading schema.exp: 0.1234s (1250 objects/s)
|
|
202
|
+
Loaded 1 schemas
|
|
203
|
+
----
|
|
204
|
+
|
|
205
|
+
==== JSON Format
|
|
206
|
+
|
|
207
|
+
Machine-readable output:
|
|
208
|
+
|
|
209
|
+
[source,bash]
|
|
210
|
+
----
|
|
211
|
+
expressir benchmark schema.exp --format json
|
|
212
|
+
----
|
|
213
|
+
|
|
214
|
+
[source,json]
|
|
215
|
+
----
|
|
216
|
+
{
|
|
217
|
+
"label": "schema.exp",
|
|
218
|
+
"time_seconds": 0.1234,
|
|
219
|
+
"objects_per_second": 1250
|
|
220
|
+
}
|
|
221
|
+
----
|
|
222
|
+
|
|
223
|
+
For multiple files:
|
|
224
|
+
|
|
225
|
+
[source,json]
|
|
226
|
+
----
|
|
227
|
+
{
|
|
228
|
+
"files_processed": 3,
|
|
229
|
+
"schemas_loaded": 5,
|
|
230
|
+
"total_objects": 3750,
|
|
231
|
+
"total_time_seconds": 0.4567,
|
|
232
|
+
"average_time_seconds": 0.1522,
|
|
233
|
+
"objects_per_second": 8210.18
|
|
234
|
+
}
|
|
235
|
+
----
|
|
236
|
+
|
|
237
|
+
==== CSV Format
|
|
238
|
+
|
|
239
|
+
Spreadsheet-compatible output:
|
|
240
|
+
|
|
241
|
+
[source,bash]
|
|
242
|
+
----
|
|
243
|
+
expressir benchmark schemas.yml --format csv
|
|
244
|
+
----
|
|
245
|
+
|
|
246
|
+
[source,csv]
|
|
247
|
+
----
|
|
248
|
+
Files,Schemas,Objects,Total Time (s),Avg Time (s),Objects/s
|
|
249
|
+
3,5,3750,0.4567,0.1522,8210.18
|
|
250
|
+
----
|
|
251
|
+
|
|
252
|
+
=== Schema Manifest Benchmarking
|
|
253
|
+
|
|
254
|
+
==== Create Schema Manifest
|
|
255
|
+
|
|
256
|
+
Create `schemas.yml`:
|
|
257
|
+
|
|
258
|
+
[source,yaml]
|
|
259
|
+
----
|
|
260
|
+
schemas:
|
|
261
|
+
- path: schemas/action_schema.exp
|
|
262
|
+
id: action_schema
|
|
263
|
+
- path: schemas/approval_schema.exp
|
|
264
|
+
id: approval_schema
|
|
265
|
+
- path: schemas/date_time_schema.exp
|
|
266
|
+
id: date_time_schema
|
|
267
|
+
----
|
|
268
|
+
|
|
269
|
+
==== Benchmark Manifest
|
|
270
|
+
|
|
271
|
+
[source,bash]
|
|
272
|
+
----
|
|
273
|
+
# Basic manifest benchmark
|
|
274
|
+
expressir benchmark schemas.yml
|
|
275
|
+
|
|
276
|
+
# With verbose output
|
|
277
|
+
expressir benchmark schemas.yml --verbose
|
|
278
|
+
----
|
|
279
|
+
|
|
280
|
+
Output:
|
|
281
|
+
[source]
|
|
282
|
+
----
|
|
283
|
+
Express Schema Loading Benchmark from Manifest
|
|
284
|
+
--------------------------------
|
|
285
|
+
Manifest File: schemas.yml
|
|
286
|
+
Number of schemas in list: 3
|
|
287
|
+
--------------------------------
|
|
288
|
+
1/3 Processing schemas/action_schema.exp
|
|
289
|
+
Loading schemas/action_schema.exp: 0.1234s (1250 objects/s)
|
|
290
|
+
2/3 Processing schemas/approval_schema.exp
|
|
291
|
+
Loading schemas/approval_schema.exp: 0.0987s (950 objects/s)
|
|
292
|
+
3/3 Processing schemas/date_time_schema.exp
|
|
293
|
+
Loading schemas/date_time_schema.exp: 0.0456s (600 objects/s)
|
|
294
|
+
|
|
295
|
+
Processed 3 files in 0.2677s
|
|
296
|
+
Loaded 5 schemas containing 2800 objects
|
|
297
|
+
Average time per file: 0.0892s
|
|
298
|
+
Performance: 10460.36 objects/s
|
|
299
|
+
----
|
|
300
|
+
|
|
301
|
+
==== Benchmark Manifest with Caching
|
|
302
|
+
|
|
303
|
+
[source,bash]
|
|
304
|
+
----
|
|
305
|
+
expressir benchmark-cache schemas.yml --cache_path /tmp/schemas_cache.bin --verbose
|
|
306
|
+
----
|
|
307
|
+
|
|
308
|
+
=== Use Cases
|
|
309
|
+
|
|
310
|
+
==== Performance Testing
|
|
311
|
+
|
|
312
|
+
Compare schema loading speeds:
|
|
313
|
+
|
|
314
|
+
[source,bash]
|
|
315
|
+
----
|
|
316
|
+
#!/bin/bash
|
|
317
|
+
# benchmark-all.sh
|
|
318
|
+
|
|
319
|
+
echo "Benchmarking schemas..."
|
|
320
|
+
|
|
321
|
+
for schema in schemas/*.exp; do
|
|
322
|
+
echo "Testing: $schema"
|
|
323
|
+
expressir benchmark "$schema" --format json | jq '.time_seconds'
|
|
324
|
+
done
|
|
325
|
+
----
|
|
326
|
+
|
|
327
|
+
==== Optimization Workflow
|
|
328
|
+
|
|
329
|
+
[source,bash]
|
|
330
|
+
----
|
|
331
|
+
# 1. Baseline benchmark
|
|
332
|
+
expressir benchmark schema.exp --verbose > baseline.txt
|
|
333
|
+
|
|
334
|
+
# 2. Make optimizations to schema
|
|
335
|
+
|
|
336
|
+
# 3. Re-benchmark
|
|
337
|
+
expressir benchmark schema.exp --verbose > optimized.txt
|
|
338
|
+
|
|
339
|
+
# 4. Compare results
|
|
340
|
+
diff baseline.txt optimized.txt
|
|
341
|
+
----
|
|
342
|
+
|
|
343
|
+
==== Cache Performance Analysis
|
|
344
|
+
|
|
345
|
+
[source,bash]
|
|
346
|
+
----
|
|
347
|
+
#!/bin/bash
|
|
348
|
+
# analyze-cache-performance.sh
|
|
349
|
+
|
|
350
|
+
echo "Analyzing cache performance..."
|
|
351
|
+
|
|
352
|
+
# Benchmark with caching
|
|
353
|
+
expressir benchmark-cache schemas.yml --cache_path /tmp/cache.bin --verbose > cache_results.txt
|
|
354
|
+
|
|
355
|
+
# Extract times
|
|
356
|
+
PARSE_TIME=$(grep "Parsing time:" cache_results.txt | awk '{print $3}')
|
|
357
|
+
READ_TIME=$(grep "Cache read time:" cache_results.txt | awk '{print $4}')
|
|
358
|
+
|
|
359
|
+
# Calculate speedup
|
|
360
|
+
SPEEDUP=$(echo "scale=2; $PARSE_TIME / $READ_TIME" | bc)
|
|
361
|
+
|
|
362
|
+
echo "Cache provides ${SPEEDUP}x speedup"
|
|
363
|
+
----
|
|
364
|
+
|
|
365
|
+
==== CI/CD Performance Monitoring
|
|
366
|
+
|
|
367
|
+
Track performance over time:
|
|
368
|
+
|
|
369
|
+
[source,bash]
|
|
370
|
+
----
|
|
371
|
+
#!/bin/bash
|
|
372
|
+
# ci-benchmark.sh
|
|
373
|
+
|
|
374
|
+
DATE=$(date +%Y%m%d)
|
|
375
|
+
OUTPUT="benchmarks/${DATE}_results.json"
|
|
376
|
+
|
|
377
|
+
mkdir -p benchmarks
|
|
378
|
+
|
|
379
|
+
# Benchmark all schemas
|
|
380
|
+
expressir benchmark schemas.yml --format json > "$OUTPUT"
|
|
381
|
+
|
|
382
|
+
# Extract key metrics
|
|
383
|
+
TOTAL_TIME=$(jq '.total_time_seconds' "$OUTPUT")
|
|
384
|
+
THROUGHPUT=$(jq '.objects_per_second' "$OUTPUT")
|
|
385
|
+
|
|
386
|
+
echo "Date: $DATE"
|
|
387
|
+
echo "Total time: ${TOTAL_TIME}s"
|
|
388
|
+
echo "Throughput: ${THROUGHPUT} objects/s"
|
|
389
|
+
|
|
390
|
+
# Check if performance degraded
|
|
391
|
+
THRESHOLD=5000
|
|
392
|
+
if (( $(echo "$THROUGHPUT < $THRESHOLD" | bc -l) )); then
|
|
393
|
+
echo "⚠️ Performance below threshold!"
|
|
394
|
+
exit 1
|
|
395
|
+
fi
|
|
396
|
+
|
|
397
|
+
echo "✓ Performance acceptable"
|
|
398
|
+
----
|
|
399
|
+
|
|
400
|
+
==== Comparing Parser Versions
|
|
401
|
+
|
|
402
|
+
[source,bash]
|
|
403
|
+
----
|
|
404
|
+
#!/bin/bash
|
|
405
|
+
# compare-versions.sh
|
|
406
|
+
|
|
407
|
+
# Test with current version
|
|
408
|
+
echo "Testing current version..."
|
|
409
|
+
expressir benchmark schemas.yml --format json > current.json
|
|
410
|
+
|
|
411
|
+
# Upgrade gem
|
|
412
|
+
gem update expressir
|
|
413
|
+
|
|
414
|
+
# Test with new version
|
|
415
|
+
echo "Testing new version..."
|
|
416
|
+
expressir benchmark schemas.yml --format json > new.json
|
|
417
|
+
|
|
418
|
+
# Compare
|
|
419
|
+
echo "Performance comparison:"
|
|
420
|
+
echo "Current: $(jq '.objects_per_second' current.json) objects/s"
|
|
421
|
+
echo "New: $(jq '.objects_per_second' new.json) objects/s"
|
|
422
|
+
----
|
|
423
|
+
|
|
424
|
+
=== Benchmark Workflows
|
|
425
|
+
|
|
426
|
+
==== Development Workflow
|
|
427
|
+
|
|
428
|
+
[source,bash]
|
|
429
|
+
----
|
|
430
|
+
# 1. Edit schema
|
|
431
|
+
vim schema.exp
|
|
432
|
+
|
|
433
|
+
# 2. Validate
|
|
434
|
+
expressir validate schema.exp
|
|
435
|
+
|
|
436
|
+
# 3. Benchmark
|
|
437
|
+
expressir benchmark schema.exp --verbose
|
|
438
|
+
|
|
439
|
+
# 4. If satisfactory, commit
|
|
440
|
+
git add schema.exp
|
|
441
|
+
git commit -m "Optimize schema structure"
|
|
442
|
+
----
|
|
443
|
+
|
|
444
|
+
==== Performance Optimization
|
|
445
|
+
|
|
446
|
+
[source,bash]
|
|
447
|
+
----
|
|
448
|
+
# 1. Establish baseline
|
|
449
|
+
expressir benchmark schemas/ --format json > baseline.json
|
|
450
|
+
|
|
451
|
+
# 2. Identify slow schemas
|
|
452
|
+
jq '.files[] | select(.time_seconds > 0.5)' baseline.json
|
|
453
|
+
|
|
454
|
+
# 3. Optimize identified schemas
|
|
455
|
+
# (refactor, split, simplify)
|
|
456
|
+
|
|
457
|
+
# 4. Re-benchmark
|
|
458
|
+
expressir benchmark schemas/ --format json > optimized.json
|
|
459
|
+
|
|
460
|
+
# 5. Compare improvement
|
|
461
|
+
python compare_benchmarks.py baseline.json optimized.json
|
|
462
|
+
----
|
|
463
|
+
|
|
464
|
+
==== Large Schema Analysis
|
|
465
|
+
|
|
466
|
+
[source,bash]
|
|
467
|
+
----
|
|
468
|
+
#!/bin/bash
|
|
469
|
+
# analyze-large-schema.sh
|
|
470
|
+
|
|
471
|
+
SCHEMA="large_schema.exp"
|
|
472
|
+
|
|
473
|
+
echo "Analyzing $SCHEMA performance..."
|
|
474
|
+
|
|
475
|
+
# Standard benchmark
|
|
476
|
+
echo "=== Standard Benchmark ==="
|
|
477
|
+
expressir benchmark "$SCHEMA" --verbose
|
|
478
|
+
|
|
479
|
+
# IPS benchmark for detailed stats
|
|
480
|
+
echo ""
|
|
481
|
+
echo "=== IPS Benchmark ==="
|
|
482
|
+
expressir benchmark "$SCHEMA" --ips
|
|
483
|
+
|
|
484
|
+
# Cache performance
|
|
485
|
+
echo ""
|
|
486
|
+
echo "=== Cache Performance ==="
|
|
487
|
+
expressir benchmark-cache "$SCHEMA" --verbose
|
|
488
|
+
----
|
|
489
|
+
|
|
490
|
+
=== Performance Metrics
|
|
491
|
+
|
|
492
|
+
==== Understanding Metrics
|
|
493
|
+
|
|
494
|
+
**Time (seconds)**::
|
|
495
|
+
Total wall-clock time to parse the schema
|
|
496
|
+
+
|
|
497
|
+
Lower is better
|
|
498
|
+
|
|
499
|
+
**Objects per second**::
|
|
500
|
+
Throughput of schema elements processed
|
|
501
|
+
+
|
|
502
|
+
Higher is better
|
|
503
|
+
+
|
|
504
|
+
Calculated as: `(total_objects / time_seconds)`
|
|
505
|
+
|
|
506
|
+
**Iterations per second (IPS)**::
|
|
507
|
+
How many complete parse operations per second
|
|
508
|
+
+
|
|
509
|
+
Higher is better
|
|
510
|
+
+
|
|
511
|
+
Only available with `--ips` option
|
|
512
|
+
|
|
513
|
+
**Cache speedup**::
|
|
514
|
+
Ratio of parse time to cache read time
|
|
515
|
+
+
|
|
516
|
+
Typical range: 10x - 100x speedup
|
|
517
|
+
|
|
518
|
+
==== Interpreting Results
|
|
519
|
+
|
|
520
|
+
[source]
|
|
521
|
+
----
|
|
522
|
+
# Good performance
|
|
523
|
+
Loading schema.exp: 0.0234s (50000 objects/s)
|
|
524
|
+
|
|
525
|
+
# Acceptable performance
|
|
526
|
+
Loading schema.exp: 0.1234s (10000 objects/s)
|
|
527
|
+
|
|
528
|
+
# Slow performance (needs investigation)
|
|
529
|
+
Loading schema.exp: 1.2345s (1000 objects/s)
|
|
530
|
+
----
|
|
531
|
+
|
|
532
|
+
Factors affecting performance:
|
|
533
|
+
|
|
534
|
+
* Schema complexity
|
|
535
|
+
* Number of entities and types
|
|
536
|
+
* Expression complexity
|
|
537
|
+
* Reference resolution
|
|
538
|
+
* System resources
|
|
539
|
+
|
|
540
|
+
=== Advanced Usage
|
|
541
|
+
|
|
542
|
+
==== Save Benchmark Results
|
|
543
|
+
|
|
544
|
+
[source,bash]
|
|
545
|
+
----
|
|
546
|
+
# Save detailed results
|
|
547
|
+
expressir benchmark schema.exp --ips --save
|
|
548
|
+
# Creates: expressir_benchmark_schema.exp file
|
|
549
|
+
----
|
|
550
|
+
|
|
551
|
+
==== Batch Benchmarking
|
|
552
|
+
|
|
553
|
+
[source,bash]
|
|
554
|
+
----
|
|
555
|
+
#!/bin/bash
|
|
556
|
+
# batch-benchmark.sh
|
|
557
|
+
|
|
558
|
+
RESULTS_DIR="benchmark_results"
|
|
559
|
+
mkdir -p "$RESULTS_DIR"
|
|
560
|
+
|
|
561
|
+
for schema in schemas/**/*.exp; do
|
|
562
|
+
basename=$(basename "$schema" .exp)
|
|
563
|
+
echo "Benchmarking $basename..."
|
|
564
|
+
|
|
565
|
+
expressir benchmark "$schema" --format json > \
|
|
566
|
+
"$RESULTS_DIR/${basename}_benchmark.json"
|
|
567
|
+
done
|
|
568
|
+
|
|
569
|
+
echo "All benchmarks complete"
|
|
570
|
+
----
|
|
571
|
+
|
|
572
|
+
==== Statistical Analysis
|
|
573
|
+
|
|
574
|
+
[source,bash]
|
|
575
|
+
----
|
|
576
|
+
#!/bin/bash
|
|
577
|
+
# Run multiple iterations for statistical analysis
|
|
578
|
+
|
|
579
|
+
SCHEMA="schema.exp"
|
|
580
|
+
ITERATIONS=10
|
|
581
|
+
|
|
582
|
+
echo "Running $ITERATIONS benchmark iterations..."
|
|
583
|
+
|
|
584
|
+
for i in $(seq 1 $ITERATIONS); do
|
|
585
|
+
expressir benchmark "$SCHEMA" --format json | \
|
|
586
|
+
jq '.time_seconds' >> times.txt
|
|
587
|
+
done
|
|
588
|
+
|
|
589
|
+
# Calculate statistics
|
|
590
|
+
echo "Statistics:"
|
|
591
|
+
echo "Min: $(sort -n times.txt | head -1)"
|
|
592
|
+
echo "Max: $(sort -n times.txt | tail -1)"
|
|
593
|
+
echo "Avg: $(awk '{sum+=$1} END {print sum/NR}' times.txt)"
|
|
594
|
+
|
|
595
|
+
rm times.txt
|
|
596
|
+
----
|
|
597
|
+
|
|
598
|
+
==== Memory Profiling
|
|
599
|
+
|
|
600
|
+
Combine with memory profiling tools:
|
|
601
|
+
|
|
602
|
+
[source,bash]
|
|
603
|
+
----
|
|
604
|
+
# Using Ruby memory profiler
|
|
605
|
+
ruby -r memory_profiler <<EOF
|
|
606
|
+
result = MemoryProfiler.report do
|
|
607
|
+
system("expressir benchmark schema.exp")
|
|
608
|
+
end
|
|
609
|
+
result.pretty_print
|
|
610
|
+
EOF
|
|
611
|
+
----
|
|
612
|
+
|
|
613
|
+
=== Integration Examples
|
|
614
|
+
|
|
615
|
+
==== GitHub Actions
|
|
616
|
+
|
|
617
|
+
[source,yaml]
|
|
618
|
+
----
|
|
619
|
+
name: Performance Benchmark
|
|
620
|
+
|
|
621
|
+
on: [push, pull_request]
|
|
622
|
+
|
|
623
|
+
jobs:
|
|
624
|
+
benchmark:
|
|
625
|
+
runs-on: ubuntu-latest
|
|
626
|
+
steps:
|
|
627
|
+
- uses: actions/checkout@v2
|
|
628
|
+
|
|
629
|
+
- name: Install Expressir
|
|
630
|
+
run: gem install expressir
|
|
631
|
+
|
|
632
|
+
- name: Benchmark Schemas
|
|
633
|
+
run: |
|
|
634
|
+
expressir benchmark schemas.yml --format json > results.json
|
|
635
|
+
|
|
636
|
+
- name: Check Performance
|
|
637
|
+
run: |
|
|
638
|
+
THROUGHPUT=$(jq '.objects_per_second' results.json)
|
|
639
|
+
THRESHOLD=5000
|
|
640
|
+
|
|
641
|
+
if (( $(echo "$THROUGHPUT < $THRESHOLD" | bc -l) )); then
|
|
642
|
+
echo "Performance degraded: ${THROUGHPUT} objects/s"
|
|
643
|
+
exit 1
|
|
644
|
+
fi
|
|
645
|
+
|
|
646
|
+
echo "Performance acceptable: ${THROUGHPUT} objects/s"
|
|
647
|
+
|
|
648
|
+
- name: Upload Results
|
|
649
|
+
uses: actions/upload-artifact@v2
|
|
650
|
+
with:
|
|
651
|
+
name: benchmark-results
|
|
652
|
+
path: results.json
|
|
653
|
+
----
|
|
654
|
+
|
|
655
|
+
==== Makefile Integration
|
|
656
|
+
|
|
657
|
+
[source,makefile]
|
|
658
|
+
----
|
|
659
|
+
.PHONY: benchmark benchmark-cache benchmark-save
|
|
660
|
+
|
|
661
|
+
benchmark:
|
|
662
|
+
@echo "Benchmarking schemas..."
|
|
663
|
+
@expressir benchmark schemas.yml --verbose
|
|
664
|
+
|
|
665
|
+
benchmark-cache:
|
|
666
|
+
@echo "Benchmarking with cache..."
|
|
667
|
+
@expressir benchmark-cache schemas.yml \
|
|
668
|
+
--cache_path .cache/schemas.bin \
|
|
669
|
+
--verbose
|
|
670
|
+
|
|
671
|
+
benchmark-save:
|
|
672
|
+
@mkdir -p benchmark_results
|
|
673
|
+
@DATE=$$(date +%Y%m%d_%H%M%S) && \
|
|
674
|
+
expressir benchmark schemas.yml --format json > \
|
|
675
|
+
benchmark_results/$${DATE}_results.json
|
|
676
|
+
@echo "Results saved to benchmark_results/"
|
|
677
|
+
----
|
|
678
|
+
|
|
679
|
+
==== Jenkins Pipeline
|
|
680
|
+
|
|
681
|
+
[source,groovy]
|
|
682
|
+
----
|
|
683
|
+
pipeline {
|
|
684
|
+
agent any
|
|
685
|
+
stages {
|
|
686
|
+
stage('Benchmark') {
|
|
687
|
+
steps {
|
|
688
|
+
sh 'gem install expressir'
|
|
689
|
+
sh 'expressir benchmark schemas.yml --format json > results.json'
|
|
690
|
+
|
|
691
|
+
script {
|
|
692
|
+
def results = readJSON file: 'results.json'
|
|
693
|
+
def throughput = results.objects_per_second
|
|
694
|
+
|
|
695
|
+
if (throughput < 5000) {
|
|
696
|
+
error("Performance below threshold: ${throughput} objects/s")
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
echo "Performance: ${throughput} objects/s"
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
----
|
|
706
|
+
|
|
707
|
+
=== Troubleshooting
|
|
708
|
+
|
|
709
|
+
==== Inconsistent Results
|
|
710
|
+
|
|
711
|
+
**Problem**: Benchmark results vary between runs
|
|
712
|
+
|
|
713
|
+
**Solutions**:
|
|
714
|
+
* Use `--ips` for more stable measurements
|
|
715
|
+
* Run multiple iterations and average
|
|
716
|
+
* Close other applications
|
|
717
|
+
* Use dedicated benchmarking environment
|
|
718
|
+
|
|
719
|
+
==== Slow Benchmarks
|
|
720
|
+
|
|
721
|
+
**Problem**: Benchmarking takes too long
|
|
722
|
+
|
|
723
|
+
**Solutions**:
|
|
724
|
+
* Benchmark individual files first
|
|
725
|
+
* Use smaller schema subsets for testing
|
|
726
|
+
* Skip `--ips` for faster results
|
|
727
|
+
* Use caching for repeated tests
|
|
728
|
+
|
|
729
|
+
==== Memory Issues
|
|
730
|
+
|
|
731
|
+
**Problem**: Out of memory during benchmarking
|
|
732
|
+
|
|
733
|
+
**Solutions**:
|
|
734
|
+
* Benchmark files individually
|
|
735
|
+
* Increase system memory
|
|
736
|
+
* Consider schema splitting
|
|
737
|
+
* Use incremental loading
|
|
738
|
+
|
|
739
|
+
==== Cache Not Improving Performance
|
|
740
|
+
|
|
741
|
+
**Problem**: Cache read time similar to parse time
|
|
742
|
+
|
|
743
|
+
**Causes**:
|
|
744
|
+
* Cache file on slow storage (network drive)
|
|
745
|
+
* Very small schemas (overhead dominates)
|
|
746
|
+
* Corrupted cache file
|
|
747
|
+
|
|
748
|
+
**Solutions**:
|
|
749
|
+
[source,bash]
|
|
750
|
+
----
|
|
751
|
+
# Use fast local storage
|
|
752
|
+
expressir benchmark-cache schema.exp --cache_path /tmp/cache.bin
|
|
753
|
+
|
|
754
|
+
# Rebuild cache
|
|
755
|
+
rm /tmp/cache.bin
|
|
756
|
+
expressir benchmark-cache schema.exp --cache_path /tmp/cache.bin
|
|
757
|
+
----
|
|
758
|
+
|
|
759
|
+
=== Best Practices
|
|
760
|
+
|
|
761
|
+
**Benchmark Regularly**::
|
|
762
|
+
Track performance over time to catch regressions
|
|
763
|
+
+
|
|
764
|
+
[source,bash]
|
|
765
|
+
----
|
|
766
|
+
# Weekly performance check
|
|
767
|
+
expressir benchmark schemas.yml --format json > weekly_benchmark.json
|
|
768
|
+
----
|
|
769
|
+
|
|
770
|
+
**Use Consistent Environment**::
|
|
771
|
+
Run benchmarks on same hardware for comparability
|
|
772
|
+
|
|
773
|
+
**Warm Up System**::
|
|
774
|
+
Run a few iterations before timing for accurate results
|
|
775
|
+
|
|
776
|
+
**Save Historical Data**::
|
|
777
|
+
Keep benchmark results for trend analysis
|
|
778
|
+
+
|
|
779
|
+
[source,bash]
|
|
780
|
+
----
|
|
781
|
+
DATE=$(date +%Y%m%d)
|
|
782
|
+
expressir benchmark schemas.yml --format json > "results_${DATE}.json"
|
|
783
|
+
----
|
|
784
|
+
|
|
785
|
+
**Combine with Validation**::
|
|
786
|
+
Ensure schemas are valid before benchmarking
|
|
787
|
+
+
|
|
788
|
+
[source,bash]
|
|
789
|
+
----
|
|
790
|
+
expressir validate schema.exp && expressir benchmark schema.exp
|
|
791
|
+
----
|
|
792
|
+
|
|
793
|
+
**Use Caching for Development**::
|
|
794
|
+
Speed up repeated processing with cache
|
|
795
|
+
+
|
|
796
|
+
[source,bash]
|
|
797
|
+
----
|
|
798
|
+
# First time: parse and cache
|
|
799
|
+
expressir benchmark-cache schemas.yml --cache_path .cache/schemas.bin
|
|
800
|
+
|
|
801
|
+
# Subsequent times: use cached version
|
|
802
|
+
# (manual loading with Ruby API)
|
|
803
|
+
----
|
|
804
|
+
|
|
805
|
+
=== Next Steps
|
|
806
|
+
|
|
807
|
+
**Related Commands**::
|
|
808
|
+
* link:validate-schemas.html[Validate Schemas] - Ensure correctness
|
|
809
|
+
* link:coverage-analysis.html[Coverage Analysis] - Check documentation
|
|
810
|
+
* link:format-schemas.html[Format Schemas] - Optimize structure
|
|
811
|
+
|
|
812
|
+
**Advanced Topics**::
|
|
813
|
+
* link:../ruby-api/parsing-files.html[Ruby API Parsing] - Programmatic benchmarking
|
|
814
|
+
* Custom performance monitoring
|
|
815
|
+
* Profiling and optimization
|
|
816
|
+
|
|
817
|
+
**Tools and Integration**::
|
|
818
|
+
* link:../deployment/ci-cd-setup.html[CI/CD Setup] - Automated monitoring
|
|
819
|
+
* Performance regression detection
|
|
820
|
+
* Historical trend analysis
|
|
821
|
+
|
|
822
|
+
=== Summary
|
|
823
|
+
|
|
824
|
+
The benchmark commands:
|
|
825
|
+
|
|
826
|
+
* ✅ Measure parsing and loading performance
|
|
827
|
+
* ✅ Support single files and manifests
|
|
828
|
+
* ✅ Provide multiple output formats (text, JSON, CSV)
|
|
829
|
+
* ✅ Offer cache performance comparison
|
|
830
|
+
* ✅ Enable performance tracking over time
|
|
831
|
+
* ✅ Integrate easily with CI/CD pipelines
|
|
832
|
+
* ✅ Support both quick checks and detailed analysis
|
|
833
|
+
|
|
834
|
+
Use benchmarking regularly to maintain optimal schema processing performance and catch performance regressions early.
|