1
1
require "benchmark/ips"
2
2
require "json"
3
3
require "oj"
4
- require "rapidjson"
4
+
5
+ Oj . default_options = Oj . default_options . merge ( mode : :compat )
5
6
6
7
if ENV [ "ONLY" ]
7
8
RUN = ENV [ "ONLY" ] . split ( /[,: ]/ ) . map { |x | [ x . to_sym , true ] } . to_h
15
16
16
17
def implementations ( ruby_obj )
17
18
state = JSON ::State . new ( JSON . dump_default_options )
18
-
19
19
{
20
20
json_state : [ "json (reuse)" , proc { state . generate ( ruby_obj ) } ] ,
21
21
json : [ "json" , proc { JSON . dump ( ruby_obj ) } ] ,
22
22
oj : [ "oj" , proc { Oj . dump ( ruby_obj ) } ] ,
23
- rapidjson : [ "rapidjson" , proc { RapidJSON . dump ( ruby_obj ) } ] ,
24
23
}
25
24
end
26
25
@@ -38,6 +37,11 @@ def benchmark_encoding(benchmark_name, ruby_obj, check_expected: true, except: [
38
37
result = block . call
39
38
if check_expected && expected != result
40
39
puts "#{ name } does not match expected output. Skipping"
40
+ puts "Expected:" + '-' * 40
41
+ puts expected
42
+ puts "Actual:" + '-' * 40
43
+ puts result
44
+ puts '-' * 40
41
45
next
42
46
end
43
47
rescue => error
@@ -67,12 +71,13 @@ def benchmark_encoding(benchmark_name, ruby_obj, check_expected: true, except: [
67
71
68
72
# This benchmark spent the overwhelming majority of its time in `ruby_dtoa`. We rely on Ruby's implementation
69
73
# which uses a relatively old version of dtoa.c from David M. Gay.
70
- # Oj is noticeably faster here because it limits the precision of floats, breaking roundtriping. That's not
71
- # something we should emulate.
74
+ # Oj in `compat` mode is ~10% slower than `json`, but in its default mode is noticeably faster here because
75
+ # it limits the precision of floats, breaking roundtriping. That's not something we should emulate.
76
+ #
72
77
# Since a few years there are now much faster float to string implementations such as Ryu, Dragonbox, etc,
73
78
# but all these are implemented in C++11 or newer, making it hard if not impossible to include them.
74
79
# Short of a pure C99 implementation of these newer algorithms, there isn't much that can be done to match
75
80
# Oj speed without losing precision.
76
81
benchmark_encoding "canada.json" , JSON . load_file ( "#{ __dir__ } /data/canada.json" ) , check_expected : false , except : %i( json_state )
77
82
78
- benchmark_encoding "many #to_json calls" , [ { Object . new => Object . new , 12 => 54.3 , Integer => Float , Time . now => Date . today } ] * 20 , except : %i( json_state )
83
+ benchmark_encoding "many #to_json calls" , [ { object : Object . new , int : 12 , float : 54.3 , class : Float , time : Time . now , date : Date . today } ] * 20 , except : %i( json_state )
0 commit comments