Skip to content

feat: make oj optional and add oj vs JSON gem benchmark comparison#40

Open
ElMassimo wants to merge 7 commits intomainfrom
claude/add-performance-benchmarks-7lIqO
Open

feat: make oj optional and add oj vs JSON gem benchmark comparison#40
ElMassimo wants to merge 7 commits intomainfrom
claude/add-performance-benchmarks-7lIqO

Conversation

@ElMassimo
Copy link
Copy Markdown
Owner

  • Create pure-Ruby JsonWriter that implements Oj::StringWriter API via
    string concatenation, enabling the library to work without the oj gem
  • Make oj a soft dependency: loads oj if available, falls back to json gem
  • Add JSON::Fragment support in JsonValue for pre-encoded JSON embedding
  • Create benchmark harness comparing oj vs Ruby's built-in JSON gem:
    • benchmarks/runner.rb: standalone runner with --backend=oj|json flag
    • benchmarks/run_comparison.rb: orchestrator spawning isolated processes
    • benchmarks/generate_charts.rb: HTML chart generator with Chart.js
  • Store benchmark results and comparison charts in benchmarks/results/
  • Update oj to 3.16.16, json gem to 2.19.2

Key findings (Ruby 3.3.6, no YJIT):

  • Hash path + JSON.generate matches or beats Oj for all scenarios
  • Pure-Ruby JsonWriter is ~1.7x slower than Oj::StringWriter
  • The json gem has closed the gap significantly with oj

https://claude.ai/code/session_018LrqGa8M4Cnvt8cZ2489Vn

claude added 7 commits March 20, 2026 12:03
- Create pure-Ruby JsonWriter that implements Oj::StringWriter API via
  string concatenation, enabling the library to work without the oj gem
- Make oj a soft dependency: loads oj if available, falls back to json gem
- Add JSON::Fragment support in JsonValue for pre-encoded JSON embedding
- Create benchmark harness comparing oj vs Ruby's built-in JSON gem:
  - benchmarks/runner.rb: standalone runner with --backend=oj|json flag
  - benchmarks/run_comparison.rb: orchestrator spawning isolated processes
  - benchmarks/generate_charts.rb: HTML chart generator with Chart.js
- Store benchmark results and comparison charts in benchmarks/results/
- Update oj to 3.16.16, json gem to 2.19.2

Key findings (Ruby 3.3.6, no YJIT):
- Hash path + JSON.generate matches or beats Oj for all scenarios
- Pure-Ruby JsonWriter is ~1.7x slower than Oj::StringWriter
- The json gem has closed the gap significantly with oj

https://claude.ai/code/session_018LrqGa8M4Cnvt8cZ2489Vn
Remove the hard dependency on oj from the gemspec. The library now works
with either oj (for maximum performance via Oj::StringWriter) or Ruby's
built-in JSON gem (via the pure-Ruby JsonWriter fallback).

Users who want the oj backend can add `gem 'oj'` to their Gemfile.

https://claude.ai/code/session_018LrqGa8M4Cnvt8cZ2489Vn
Remove OjSerializers::JsonWriter, Oj::StringWriter integration, and all
write_ APIs (write_one, write_many, write_to_json). Remove default_format
since the format is always :hash. Simplify define_serialization_shortcuts,
cached method, and code generation to only use the hash path.

- Delete lib/oj_serializers/json_writer.rb and setup.rb
- Remove code_to_write_to_json, code_to_write_attribute, code_to_write_association
- Remove one_as_json, many_as_json, new_json_writer
- Simplify json_string_encoder to use JSON.generate
- Remove defined?(Oj) checks from json_value.rb
- Remove write_one/write_many from compat.rb
- Update all benchmarks to use JSON.generate instead of Oj.dump
- Delete gemfiles/Gemfile-json-only and spec/support/non_blank_json_writer.rb

https://claude.ai/code/session_018LrqGa8M4Cnvt8cZ2489Vn
Rename directories, files, modules, and class references throughout:
- lib/oj_serializers/ → lib/json_serializers/
- OjSerializers → JsonSerializers
- Oj::Serializer → JsonSerializer (with backward-compat alias)
- Update README to emphasize hash-based architecture and memory efficiency
- Update MIGRATION_GUIDE.md and CHANGELOG.md references

https://claude.ai/code/session_018LrqGa8M4Cnvt8cZ2489Vn
JSON.generate(LegacyAlbumSerializer.new(album)) was producing
"#<LegacyAlbumSerializer:0x...>" instead of actual serialized JSON,
because AMS 0.10 doesn't integrate with JSON.generate properly.
This made AMS appear 31x faster when it was doing zero work.

Fix all AMS benchmark invocations to use .as_json before JSON.generate,
ensuring proper serialization. json_serializers is now correctly shown
as ~3x faster than AMS.

Also add benchmark result collection and Chart.js-based framework
comparison charts (reusing the existing chart generation pattern):
- benchmark_section helper captures IPS results as JSON
- generate_framework_charts.rb produces interactive HTML + markdown
- Results auto-saved to benchmarks/results/frameworks.{json,html,md}

https://claude.ai/code/session_01GQ2r4uE7ZVjYrchMCxCX5k
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants