From f2d0402ec1fda556d03a4e5b5ffa16e9d2ca6ce9 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 15 Apr 2024 12:57:13 +0200 Subject: [PATCH] Use the pure-Ruby generator on TruffleRuby as it is much faster MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Using the benchmark from https://github.com/flori/json/pull/580 $ ruby benchmarks/bench.rb dump pure JSON::Pure::Generator truffleruby 24.0.0, like ruby 3.2.2, Oracle GraalVM Native [x86_64-linux] Warming up -------------------------------------- JSON.dump(obj) 116.000 i/100ms JSON.dump(obj) 235.000 i/100ms JSON.dump(obj) 317.000 i/100ms JSON.dump(obj) 372.000 i/100ms JSON.dump(obj) 374.000 i/100ms Calculating ------------------------------------- JSON.dump(obj) 3.735k (± 0.9%) i/s (267.76 μs/i) - 18.700k in 5.007526s JSON.dump(obj) 3.738k (± 0.7%) i/s (267.49 μs/i) - 18.700k in 5.002252s JSON.dump(obj) 3.743k (± 0.7%) i/s (267.18 μs/i) - 19.074k in 5.096375s JSON.dump(obj) 3.747k (± 0.5%) i/s (266.87 μs/i) - 19.074k in 5.090463s JSON.dump(obj) 3.746k (± 0.5%) i/s (266.96 μs/i) - 19.074k in 5.092069s $ ruby benchmarks/bench.rb dump ext JSON::Ext::Generator truffleruby 24.0.0, like ruby 3.2.2, Oracle GraalVM Native [x86_64-linux] Warming up -------------------------------------- JSON.dump(obj) 19.000 i/100ms JSON.dump(obj) 18.000 i/100ms JSON.dump(obj) 18.000 i/100ms JSON.dump(obj) 18.000 i/100ms JSON.dump(obj) 21.000 i/100ms Calculating ------------------------------------- JSON.dump(obj) 221.260 (±10.8%) i/s (4.52 ms/i) - 1.092k in 5.004381s JSON.dump(obj) 221.983 (± 8.1%) i/s (4.50 ms/i) - 1.113k in 5.055574s JSON.dump(obj) 221.446 (± 8.6%) i/s (4.52 ms/i) - 1.113k in 5.073167s JSON.dump(obj) 226.452 (± 7.9%) i/s (4.42 ms/i) - 1.134k in 5.048568s JSON.dump(obj) 227.795 (± 8.3%) i/s (4.39 ms/i) - 1.134k in 5.025187s --- Rakefile | 6 +++++- ext/json/ext/generator/extconf.rb | 9 +++++++-- lib/json/ext.rb | 18 +++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Rakefile b/Rakefile index 17c06073..55354535 100644 --- a/Rakefile +++ b/Rakefile @@ -238,7 +238,11 @@ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby' task :release => :build else desc "Compiling extension" - task :compile => [ EXT_PARSER_DL, EXT_GENERATOR_DL ] + if RUBY_ENGINE == 'truffleruby' + task :compile => [ EXT_PARSER_DL ] + else + task :compile => [ EXT_PARSER_DL, EXT_GENERATOR_DL ] + end file EXT_PARSER_DL => EXT_PARSER_SRC do cd EXT_PARSER_DIR do diff --git a/ext/json/ext/generator/extconf.rb b/ext/json/ext/generator/extconf.rb index 8627c5f4..cf8d5f2b 100644 --- a/ext/json/ext/generator/extconf.rb +++ b/ext/json/ext/generator/extconf.rb @@ -1,4 +1,9 @@ require 'mkmf' -$defs << "-DJSON_GENERATOR" -create_makefile 'json/ext/generator' +if RUBY_ENGINE == 'truffleruby' + # The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension + File.write('Makefile', dummy_makefile("").join) +else + $defs << "-DJSON_GENERATOR" + create_makefile 'json/ext/generator' +end diff --git a/lib/json/ext.rb b/lib/json/ext.rb index 7264a857..b62e2317 100644 --- a/lib/json/ext.rb +++ b/lib/json/ext.rb @@ -4,11 +4,19 @@ module JSON # This module holds all the modules/classes that implement JSON's # functionality as C extensions. module Ext - require 'json/ext/parser' - require 'json/ext/generator' - $DEBUG and warn "Using Ext extension for JSON." - JSON.parser = Parser - JSON.generator = Generator + if RUBY_ENGINE == 'truffleruby' + require 'json/ext/parser' + require 'json/pure' + $DEBUG and warn "Using Ext extension for JSON parser and Pure library for JSON generator." + JSON.parser = Parser + JSON.generator = JSON::Pure::Generator + else + require 'json/ext/parser' + require 'json/ext/generator' + $DEBUG and warn "Using Ext extension for JSON." + JSON.parser = Parser + JSON.generator = Generator + end end JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)