oj 2.18.3 → 3.13.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1324 -0
- data/README.md +51 -204
- data/RELEASE_NOTES.md +61 -0
- data/ext/oj/buf.h +49 -72
- data/ext/oj/cache.c +326 -0
- data/ext/oj/cache.h +21 -0
- data/ext/oj/cache8.c +61 -64
- data/ext/oj/cache8.h +12 -39
- data/ext/oj/circarray.c +37 -68
- data/ext/oj/circarray.h +16 -42
- data/ext/oj/code.c +221 -0
- data/ext/oj/code.h +40 -0
- data/ext/oj/compat.c +231 -107
- data/ext/oj/custom.c +1125 -0
- data/ext/oj/debug.c +132 -0
- data/ext/oj/dump.c +935 -2513
- data/ext/oj/dump.h +108 -0
- data/ext/oj/dump_compat.c +936 -0
- data/ext/oj/dump_leaf.c +164 -0
- data/ext/oj/dump_object.c +761 -0
- data/ext/oj/dump_strict.c +410 -0
- data/ext/oj/encode.h +7 -42
- data/ext/oj/encoder.c +43 -0
- data/ext/oj/err.c +40 -54
- data/ext/oj/err.h +52 -46
- data/ext/oj/extconf.rb +21 -30
- data/ext/oj/fast.c +1097 -1080
- data/ext/oj/intern.c +301 -0
- data/ext/oj/intern.h +26 -0
- data/ext/oj/mimic_json.c +893 -0
- data/ext/oj/object.c +549 -620
- data/ext/oj/odd.c +155 -167
- data/ext/oj/odd.h +37 -63
- data/ext/oj/oj.c +1661 -2063
- data/ext/oj/oj.h +341 -270
- data/ext/oj/parse.c +974 -737
- data/ext/oj/parse.h +105 -97
- data/ext/oj/parser.c +1526 -0
- data/ext/oj/parser.h +90 -0
- data/ext/oj/rails.c +1504 -0
- data/ext/oj/rails.h +18 -0
- data/ext/oj/reader.c +141 -163
- data/ext/oj/reader.h +75 -113
- data/ext/oj/resolve.c +45 -93
- data/ext/oj/resolve.h +7 -34
- data/ext/oj/rxclass.c +143 -0
- data/ext/oj/rxclass.h +26 -0
- data/ext/oj/saj.c +447 -511
- data/ext/oj/saj2.c +348 -0
- data/ext/oj/scp.c +91 -138
- data/ext/oj/sparse.c +793 -644
- data/ext/oj/stream_writer.c +331 -0
- data/ext/oj/strict.c +145 -109
- data/ext/oj/string_writer.c +493 -0
- data/ext/oj/trace.c +72 -0
- data/ext/oj/trace.h +28 -0
- data/ext/oj/usual.c +1254 -0
- data/ext/oj/util.c +136 -0
- data/ext/oj/util.h +20 -0
- data/ext/oj/val_stack.c +62 -70
- data/ext/oj/val_stack.h +95 -129
- data/ext/oj/validate.c +51 -0
- data/ext/oj/wab.c +622 -0
- data/lib/oj/bag.rb +1 -0
- data/lib/oj/easy_hash.rb +17 -8
- data/lib/oj/error.rb +10 -11
- data/lib/oj/json.rb +176 -0
- data/lib/oj/mimic.rb +158 -19
- data/lib/oj/state.rb +132 -0
- data/lib/oj/version.rb +2 -2
- data/lib/oj.rb +1 -31
- data/pages/Advanced.md +22 -0
- data/pages/Compatibility.md +25 -0
- data/pages/Custom.md +23 -0
- data/pages/Encoding.md +65 -0
- data/pages/JsonGem.md +94 -0
- data/pages/Modes.md +161 -0
- data/pages/Options.md +327 -0
- data/pages/Parser.md +309 -0
- data/pages/Rails.md +167 -0
- data/pages/Security.md +20 -0
- data/pages/WAB.md +13 -0
- data/test/activerecord/result_test.rb +32 -0
- data/test/activesupport4/decoding_test.rb +108 -0
- data/test/activesupport4/encoding_test.rb +531 -0
- data/test/activesupport4/test_helper.rb +41 -0
- data/test/activesupport5/abstract_unit.rb +45 -0
- data/test/activesupport5/decoding_test.rb +133 -0
- data/test/activesupport5/encoding_test.rb +500 -0
- data/test/activesupport5/encoding_test_cases.rb +98 -0
- data/test/activesupport5/test_helper.rb +72 -0
- data/test/activesupport5/time_zone_test_helpers.rb +39 -0
- data/test/activesupport6/abstract_unit.rb +44 -0
- data/test/activesupport6/decoding_test.rb +133 -0
- data/test/activesupport6/encoding_test.rb +507 -0
- data/test/activesupport6/encoding_test_cases.rb +98 -0
- data/test/activesupport6/test_common.rb +17 -0
- data/test/activesupport6/test_helper.rb +163 -0
- data/test/activesupport6/time_zone_test_helpers.rb +39 -0
- data/test/activesupport7/abstract_unit.rb +49 -0
- data/test/activesupport7/decoding_test.rb +125 -0
- data/test/activesupport7/encoding_test.rb +486 -0
- data/test/activesupport7/encoding_test_cases.rb +104 -0
- data/test/activesupport7/time_zone_test_helpers.rb +47 -0
- data/test/bar.rb +9 -0
- data/test/baz.rb +16 -0
- data/test/bug.rb +11 -46
- data/test/foo.rb +69 -16
- data/test/helper.rb +10 -1
- data/test/isolated/shared.rb +12 -8
- data/test/isolated/test_mimic_rails_after.rb +3 -3
- data/test/isolated/test_mimic_rails_before.rb +3 -3
- data/test/json_gem/json_addition_test.rb +216 -0
- data/test/json_gem/json_common_interface_test.rb +153 -0
- data/test/json_gem/json_encoding_test.rb +107 -0
- data/test/json_gem/json_ext_parser_test.rb +20 -0
- data/test/json_gem/json_fixtures_test.rb +35 -0
- data/test/json_gem/json_generator_test.rb +397 -0
- data/test/json_gem/json_generic_object_test.rb +90 -0
- data/test/json_gem/json_parser_test.rb +470 -0
- data/test/json_gem/json_string_matching_test.rb +42 -0
- data/test/json_gem/test_helper.rb +26 -0
- data/test/mem.rb +33 -0
- data/test/perf.rb +1 -1
- data/test/perf_compat.rb +30 -28
- data/test/perf_dump.rb +50 -0
- data/test/perf_object.rb +1 -1
- data/test/perf_once.rb +58 -0
- data/test/perf_parser.rb +189 -0
- data/test/perf_scp.rb +11 -10
- data/test/perf_strict.rb +30 -19
- data/test/perf_wab.rb +131 -0
- data/test/prec.rb +23 -0
- data/test/sample.rb +0 -1
- data/test/sample_json.rb +1 -1
- data/test/test_compat.rb +219 -102
- data/test/test_custom.rb +533 -0
- data/test/test_fast.rb +107 -35
- data/test/test_file.rb +19 -25
- data/test/test_generate.rb +21 -0
- data/test/test_hash.rb +11 -1
- data/test/test_integer_range.rb +72 -0
- data/test/test_null.rb +376 -0
- data/test/test_object.rb +357 -70
- data/test/test_parser.rb +27 -0
- data/test/test_parser_saj.rb +245 -0
- data/test/test_parser_usual.rb +217 -0
- data/test/test_rails.rb +35 -0
- data/test/test_saj.rb +1 -1
- data/test/test_scp.rb +39 -2
- data/test/test_strict.rb +186 -7
- data/test/test_various.rb +160 -774
- data/test/test_wab.rb +307 -0
- data/test/test_writer.rb +90 -2
- data/test/tests.rb +24 -0
- data/test/tests_mimic.rb +14 -0
- data/test/tests_mimic_addition.rb +7 -0
- data/test/zoo.rb +13 -0
- metadata +194 -56
- data/ext/oj/hash.c +0 -163
- data/ext/oj/hash.h +0 -46
- data/ext/oj/hash_test.c +0 -512
- data/test/activesupport_datetime_test.rb +0 -23
- data/test/bug2.rb +0 -10
- data/test/bug3.rb +0 -46
- data/test/bug_fast.rb +0 -32
- data/test/bug_load.rb +0 -24
- data/test/crash.rb +0 -111
- data/test/curl/curl_oj.rb +0 -46
- data/test/curl/get_oj.rb +0 -24
- data/test/curl/just_curl.rb +0 -31
- data/test/curl/just_oj.rb +0 -51
- data/test/example.rb +0 -11
- data/test/io.rb +0 -48
- data/test/isolated/test_mimic_rails_datetime.rb +0 -27
- data/test/mod.rb +0 -16
- data/test/rails.rb +0 -50
- data/test/russian.rb +0 -18
- data/test/struct.rb +0 -29
- data/test/test_serializer.rb +0 -59
- data/test/write_timebars.rb +0 -31
data/test/perf_dump.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << '.'
|
5
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
$: << File.join(File.dirname(__FILE__), "../ext")
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'oj'
|
10
|
+
|
11
|
+
$verbose = false
|
12
|
+
$indent = 2
|
13
|
+
$iter = 100_000
|
14
|
+
$size = 2
|
15
|
+
|
16
|
+
opts = OptionParser.new
|
17
|
+
opts.on("-v", "verbose") { $verbose = true }
|
18
|
+
opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
|
19
|
+
opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
|
20
|
+
opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
|
21
|
+
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
22
|
+
files = opts.parse(ARGV)
|
23
|
+
|
24
|
+
$obj = {
|
25
|
+
'a' => 'Alpha', # string
|
26
|
+
'b' => true, # boolean
|
27
|
+
'c' => 12345, # number
|
28
|
+
'd' => [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
|
29
|
+
'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
|
30
|
+
'f' => nil, # nil
|
31
|
+
'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
|
32
|
+
'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
|
33
|
+
}
|
34
|
+
|
35
|
+
Oj.default_options = { :indent => $indent, :mode => :strict }
|
36
|
+
|
37
|
+
if 0 < $size
|
38
|
+
o = $obj
|
39
|
+
$obj = []
|
40
|
+
(4 * $size).times do
|
41
|
+
$obj << o
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
$json = Oj.dump($obj)
|
46
|
+
GC.start
|
47
|
+
start = Time.now
|
48
|
+
$iter.times { Oj.dump($obj) }
|
49
|
+
duration = Time.now - start
|
50
|
+
puts "Dumped #{$json.length} byte JSON #{$iter} times in %0.3f seconds or %0.3f iteration/sec." % [duration, $iter / duration]
|
data/test/perf_object.rb
CHANGED
data/test/perf_once.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << '.'
|
5
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
$: << File.join(File.dirname(__FILE__), "../ext")
|
7
|
+
|
8
|
+
require 'oj'
|
9
|
+
|
10
|
+
filename = 'tmp.json'
|
11
|
+
File.open(filename, "w") { |f|
|
12
|
+
cnt = 0
|
13
|
+
f.puts('{')
|
14
|
+
('a'..'z').each { |a|
|
15
|
+
('a'..'z').each { |b|
|
16
|
+
('a'..'z').each { |c|
|
17
|
+
('a'..'z').each { |d|
|
18
|
+
f.puts(%|"#{a}#{b}#{c}#{d}":#{cnt},|)
|
19
|
+
cnt += 1
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
f.puts('"_last":0}')
|
25
|
+
}
|
26
|
+
|
27
|
+
def mem
|
28
|
+
`ps -o rss= -p #{$$}`.to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
Oj.default_options = { mode: :strict, cache_keys: false, cache_str: -1 }
|
32
|
+
start = Time.now
|
33
|
+
Oj.load_file('tmp.json')
|
34
|
+
dur = Time.now - start
|
35
|
+
GC.start
|
36
|
+
puts "no cache duration: #{dur} @ #{mem}"
|
37
|
+
|
38
|
+
Oj.default_options = { cache_keys: true }
|
39
|
+
start = Time.now
|
40
|
+
Oj.load_file('tmp.json')
|
41
|
+
dur = Time.now - start
|
42
|
+
GC.start
|
43
|
+
puts "initial cache duration: #{dur} @ #{mem}"
|
44
|
+
|
45
|
+
start = Time.now
|
46
|
+
Oj.load_file('tmp.json')
|
47
|
+
dur = Time.now - start
|
48
|
+
GC.start
|
49
|
+
puts "second cache duration: #{dur} @ #{mem}"
|
50
|
+
|
51
|
+
10.times{ GC.start }
|
52
|
+
start = Time.now
|
53
|
+
Oj.load_file('tmp.json')
|
54
|
+
dur = Time.now - start
|
55
|
+
GC.start
|
56
|
+
puts "after several GCs cache duration: #{dur} @ #{mem}"
|
57
|
+
|
58
|
+
# TBD check memory use
|
data/test/perf_parser.rb
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << '.'
|
5
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
$: << File.join(File.dirname(__FILE__), "../ext")
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'perf'
|
10
|
+
require 'oj'
|
11
|
+
require 'json'
|
12
|
+
|
13
|
+
$verbose = false
|
14
|
+
$iter = 50_000
|
15
|
+
$with_bignum = false
|
16
|
+
$size = 1
|
17
|
+
$cache_keys = true
|
18
|
+
$symbol_keys = false
|
19
|
+
|
20
|
+
opts = OptionParser.new
|
21
|
+
opts.on("-v", "verbose") { $verbose = true }
|
22
|
+
opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
|
23
|
+
opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
|
24
|
+
opts.on("-b", "with bignum") { $with_bignum = true }
|
25
|
+
opts.on("-k", "no cache") { $cache_keys = false }
|
26
|
+
opts.on("-sym", "symbol keys") { $symbol_keys = true }
|
27
|
+
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
28
|
+
files = opts.parse(ARGV)
|
29
|
+
|
30
|
+
$obj = {
|
31
|
+
'a' => 'Alpha', # string
|
32
|
+
'b' => true, # boolean
|
33
|
+
'c' => 12345, # number
|
34
|
+
'd' => [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false, 1, nil], nil]], # mix it up array
|
35
|
+
'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
|
36
|
+
'f' => nil, # nil
|
37
|
+
'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
|
38
|
+
'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
|
39
|
+
}
|
40
|
+
$obj['g'] = 12345678901234567890123456789 if $with_bignum
|
41
|
+
|
42
|
+
if 0 < $size
|
43
|
+
o = $obj
|
44
|
+
$obj = []
|
45
|
+
(4 * $size).times do
|
46
|
+
$obj << o
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
$json = Oj.dump($obj)
|
51
|
+
$failed = {} # key is same as String used in tests later
|
52
|
+
Oj.default_options = {create_id: '^', create_additions: true, class_cache: true}
|
53
|
+
if $cache_keys
|
54
|
+
Oj.default_options = {cache_keys: true, cache_str: 6, symbol_keys: $symbol_keys}
|
55
|
+
else
|
56
|
+
Oj.default_options = {cache_keys: false, cache_str: -1, symbol_keys: $symbol_keys}
|
57
|
+
end
|
58
|
+
JSON.parser = JSON::Ext::Parser
|
59
|
+
|
60
|
+
class AllSaj
|
61
|
+
def initialize()
|
62
|
+
end
|
63
|
+
|
64
|
+
def hash_start(key)
|
65
|
+
end
|
66
|
+
|
67
|
+
def hash_end(key)
|
68
|
+
end
|
69
|
+
|
70
|
+
def array_start(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
def array_end(key)
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_value(value, key)
|
77
|
+
end
|
78
|
+
end # AllSaj
|
79
|
+
|
80
|
+
class NoSaj
|
81
|
+
def initialize()
|
82
|
+
end
|
83
|
+
end # NoSaj
|
84
|
+
|
85
|
+
no_handler = NoSaj.new()
|
86
|
+
all_handler = AllSaj.new()
|
87
|
+
|
88
|
+
if $verbose
|
89
|
+
puts "json:\n#{$json}\n"
|
90
|
+
end
|
91
|
+
|
92
|
+
### Validate ######################
|
93
|
+
p_val = Oj::Parser.new(:validate)
|
94
|
+
|
95
|
+
puts '-' * 80
|
96
|
+
puts "Validate Performance"
|
97
|
+
perf = Perf.new()
|
98
|
+
perf.add('Oj::Parser.validate', 'none') { p_val.parse($json) }
|
99
|
+
perf.add('Oj::Saj.none', 'none') { Oj.saj_parse(no_handler, $json) }
|
100
|
+
perf.run($iter)
|
101
|
+
|
102
|
+
### SAJ ######################
|
103
|
+
p_all = Oj::Parser.new(:saj)
|
104
|
+
p_all.handler = all_handler
|
105
|
+
p_all.cache_keys = $cache_keys
|
106
|
+
p_all.cache_strings = 6
|
107
|
+
|
108
|
+
puts '-' * 80
|
109
|
+
puts "Parse Callback Performance"
|
110
|
+
perf = Perf.new()
|
111
|
+
perf.add('Oj::Parser.saj', 'all') { p_all.parse($json) }
|
112
|
+
perf.add('Oj::Saj.all', 'all') { Oj.saj_parse(all_handler, $json) }
|
113
|
+
perf.run($iter)
|
114
|
+
|
115
|
+
### Usual ######################
|
116
|
+
p_usual = Oj::Parser.new(:usual)
|
117
|
+
p_usual.cache_keys = $cache_keys
|
118
|
+
p_usual.cache_strings = ($cache_keys ? 6 : 0)
|
119
|
+
p_usual.symbol_keys = $symbol_keys
|
120
|
+
|
121
|
+
puts '-' * 80
|
122
|
+
puts "Parse Usual Performance"
|
123
|
+
perf = Perf.new()
|
124
|
+
perf.add('Oj::Parser.usual', '') { p_usual.parse($json) }
|
125
|
+
perf.add('Oj::strict_load', '') { Oj.strict_load($json) }
|
126
|
+
perf.add('JSON::Ext', 'parse') { JSON.load($json) }
|
127
|
+
perf.run($iter)
|
128
|
+
|
129
|
+
### Usual Objects ######################
|
130
|
+
|
131
|
+
# Original Oj follows the JSON gem for creating objects which uses the class
|
132
|
+
# json_create(arg) method. Oj::Parser in usual mode supprts the same but also
|
133
|
+
# handles populating the object variables directly which is faster.
|
134
|
+
|
135
|
+
class Stuff
|
136
|
+
attr_accessor :alpha, :bravo, :charlie, :delta, :echo, :foxtrot, :golf, :hotel, :india, :juliet
|
137
|
+
def self.json_create(arg)
|
138
|
+
obj = self.new
|
139
|
+
obj.alpha = arg["alpha"]
|
140
|
+
obj.bravo = arg["bravo"]
|
141
|
+
obj.charlie = arg["charlie"]
|
142
|
+
obj.delta = arg["delta"]
|
143
|
+
obj.echo = arg["echo"]
|
144
|
+
obj.foxtrot = arg["foxtrot"]
|
145
|
+
obj.golf = arg["golf"]
|
146
|
+
obj.hotel = arg["hotel"]
|
147
|
+
obj.india = arg["india"]
|
148
|
+
obj.juliet = arg["juliet"]
|
149
|
+
obj
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
$obj_json = %|{
|
154
|
+
"alpha": [0, 1,2,3,4,5,6,7,8,9],
|
155
|
+
"bravo": true,
|
156
|
+
"charlie": 123,
|
157
|
+
"delta": "some string",
|
158
|
+
"echo": null,
|
159
|
+
"^": "Stuff",
|
160
|
+
"foxtrot": false,
|
161
|
+
"golf": "gulp",
|
162
|
+
"hotel": {"x": true, "y": false},
|
163
|
+
"india": [null, true, 123],
|
164
|
+
"juliet": "junk"
|
165
|
+
}|
|
166
|
+
|
167
|
+
|
168
|
+
p_usual = Oj::Parser.new(:usual)
|
169
|
+
p_usual.cache_keys = $cache_keys
|
170
|
+
p_usual.cache_strings = ($cache_keys ? 6 : 0)
|
171
|
+
p_usual.symbol_keys = $symbol_keys
|
172
|
+
p_usual.create_id = '^'
|
173
|
+
p_usual.class_cache = true
|
174
|
+
p_usual.ignore_json_create = true
|
175
|
+
|
176
|
+
JSON.create_id = '^'
|
177
|
+
|
178
|
+
puts '-' * 80
|
179
|
+
puts "Parse Usual Object Performance"
|
180
|
+
perf = Perf.new()
|
181
|
+
perf.add('Oj::Parser.usual', '') { p_usual.parse($obj_json) }
|
182
|
+
perf.add('Oj::compat_load', '') { Oj.compat_load($obj_json) }
|
183
|
+
perf.add('JSON::Ext', 'parse') { JSON.load($obj_json) }
|
184
|
+
perf.run($iter)
|
185
|
+
|
186
|
+
unless $failed.empty?
|
187
|
+
puts "The following packages were not included for the reason listed"
|
188
|
+
$failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
|
189
|
+
end
|
data/test/perf_scp.rb
CHANGED
@@ -14,16 +14,16 @@ require 'oj'
|
|
14
14
|
|
15
15
|
$verbose = false
|
16
16
|
$indent = 0
|
17
|
-
$iter =
|
17
|
+
$iter = 50_000
|
18
18
|
$with_bignum = false
|
19
|
-
$size =
|
19
|
+
$size = 1
|
20
20
|
|
21
21
|
opts = OptionParser.new
|
22
22
|
opts.on("-v", "verbose") { $verbose = true }
|
23
23
|
opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
|
24
24
|
opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
|
25
|
-
opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)")
|
26
|
-
opts.on("-b", "with bignum")
|
25
|
+
opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
|
26
|
+
opts.on("-b", "with bignum") { $with_bignum = true }
|
27
27
|
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
28
28
|
files = opts.parse(ARGV)
|
29
29
|
|
@@ -47,7 +47,7 @@ if 0 < $size
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
Oj.default_options = { :indent => $indent, :mode => :
|
50
|
+
Oj.default_options = { :indent => $indent, :mode => :strict, cache_keys: true, cache_str: 5 }
|
51
51
|
|
52
52
|
$json = Oj.dump($obj)
|
53
53
|
$failed = {} # key is same as String used in tests later
|
@@ -105,7 +105,7 @@ class AllHandler < Oj::ScHandler
|
|
105
105
|
|
106
106
|
def hash_set(h, key, value)
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def array_append(a, value)
|
110
110
|
end
|
111
111
|
|
@@ -137,10 +137,11 @@ end
|
|
137
137
|
puts '-' * 80
|
138
138
|
puts "Parse Performance"
|
139
139
|
perf = Perf.new()
|
140
|
-
perf.add('Oj::Saj', 'all') { Oj.saj_parse(saj_handler, $json) }
|
141
|
-
perf.add('Oj::Saj', 'none') { Oj.saj_parse(no_saj, $json) }
|
142
|
-
perf.add('Oj::Scp', 'all') { Oj.sc_parse(sc_handler, $json) }
|
143
|
-
perf.add('Oj::Scp', 'none') { Oj.sc_parse(no_handler, $json) }
|
140
|
+
perf.add('Oj::Saj.all', 'all') { Oj.saj_parse(saj_handler, $json) }
|
141
|
+
perf.add('Oj::Saj.none', 'none') { Oj.saj_parse(no_saj, $json) }
|
142
|
+
perf.add('Oj::Scp.all', 'all') { Oj.sc_parse(sc_handler, $json) }
|
143
|
+
perf.add('Oj::Scp.none', 'none') { Oj.sc_parse(no_handler, $json) }
|
144
|
+
perf.add('Oj::load', 'none') { Oj.wab_load($json) }
|
144
145
|
perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
|
145
146
|
perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new($json).parse } unless $failed.has_key?('JSON::Ext')
|
146
147
|
perf.run($iter)
|
data/test/perf_strict.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
4
|
$: << '.'
|
@@ -15,6 +15,8 @@ $iter = 20000
|
|
15
15
|
$with_bignum = false
|
16
16
|
$with_nums = true
|
17
17
|
$size = 0
|
18
|
+
$symbolize = false
|
19
|
+
$cache_keys = true
|
18
20
|
|
19
21
|
opts = OptionParser.new
|
20
22
|
opts.on("-v", "verbose") { $verbose = true }
|
@@ -23,6 +25,8 @@ opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
|
|
23
25
|
opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
|
24
26
|
opts.on("-b", "with bignum") { $with_bignum = true }
|
25
27
|
opts.on("-n", "without numbers") { $with_nums = false }
|
28
|
+
opts.on("-z", "--symbolize", "symbolize keys") { $symbolize = true }
|
29
|
+
opts.on("-k", "--no-cache", "turn off key caching") { $cache_keys = false }
|
26
30
|
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
27
31
|
files = opts.parse(ARGV)
|
28
32
|
|
@@ -51,7 +55,7 @@ else
|
|
51
55
|
}
|
52
56
|
end
|
53
57
|
|
54
|
-
Oj.default_options = { :indent => $indent, :mode => :strict }
|
58
|
+
Oj.default_options = { :indent => $indent, :mode => :strict, cache_keys: $cache_keys, cache_str: 5 }
|
55
59
|
|
56
60
|
if 0 < $size
|
57
61
|
o = $obj
|
@@ -62,9 +66,6 @@ if 0 < $size
|
|
62
66
|
end
|
63
67
|
|
64
68
|
$json = Oj.dump($obj)
|
65
|
-
$obj_json = Oj.dump($obj, :mode => :object)
|
66
|
-
#puts "*** size: #{$obj_json.size}"
|
67
|
-
#puts "*** #{$obj_json}"
|
68
69
|
$failed = {} # key is same as String used in tests later
|
69
70
|
|
70
71
|
def capture_error(tag, orig, load_key, dump_key, &blk)
|
@@ -77,8 +78,13 @@ def capture_error(tag, orig, load_key, dump_key, &blk)
|
|
77
78
|
end
|
78
79
|
|
79
80
|
# Verify that all packages dump and load correctly and return the same Object as the original.
|
80
|
-
capture_error('Oj:strict', $obj, 'load', 'dump') { |o|
|
81
|
-
|
81
|
+
capture_error('Oj:strict', $obj, 'load', 'dump') { |o|
|
82
|
+
Oj.strict_load(Oj.dump(o))
|
83
|
+
}
|
84
|
+
capture_error('Yajl', $obj, 'encode', 'parse') { |o|
|
85
|
+
require 'yajl'
|
86
|
+
Yajl::Parser.parse(Yajl::Encoder.encode(o))
|
87
|
+
}
|
82
88
|
capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
|
83
89
|
require 'json'
|
84
90
|
require 'json/ext'
|
@@ -86,16 +92,11 @@ capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
|
|
86
92
|
JSON.parser = JSON::Ext::Parser
|
87
93
|
JSON.parse(JSON.generate(o))
|
88
94
|
}
|
89
|
-
|
90
|
-
|
91
|
-
JSON.generator = JSON::Pure::Generator
|
92
|
-
JSON.parser = JSON::Pure::Parser
|
93
|
-
JSON.parse(JSON.generate(o))
|
94
|
-
}
|
95
|
+
|
96
|
+
Oj.default_options = { symbol_keys: $symbolize }
|
95
97
|
|
96
98
|
if $verbose
|
97
99
|
puts "json:\n#{$json}\n"
|
98
|
-
puts "object json:\n#{$obj_json}\n"
|
99
100
|
puts "Oj loaded object:\n#{Oj.strict_load($json)}\n"
|
100
101
|
puts "Yajl loaded object:\n#{Yajl::Parser.parse($json)}\n"
|
101
102
|
puts "JSON loaded object:\n#{JSON::Ext::Parser.new($json).parse}\n"
|
@@ -105,19 +106,29 @@ puts '-' * 80
|
|
105
106
|
puts "Strict Parse Performance"
|
106
107
|
perf = Perf.new()
|
107
108
|
unless $failed.has_key?('JSON::Ext')
|
108
|
-
perf.add('JSON::Ext', 'parse') { JSON.parse($json) }
|
109
|
+
perf.add('JSON::Ext', 'parse') { JSON.parse($json, symbolize_names: $symbolize) }
|
109
110
|
perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
|
110
111
|
end
|
111
|
-
unless $failed.has_key?('JSON::Pure')
|
112
|
-
perf.add('JSON::Pure', 'parse') { JSON.parse($json) }
|
113
|
-
perf.before('JSON::Pure') { JSON.parser = JSON::Pure::Parser }
|
114
|
-
end
|
115
112
|
unless $failed.has_key?('Oj:strict')
|
116
113
|
perf.add('Oj:strict', 'strict_load') { Oj.strict_load($json) }
|
114
|
+
perf.add('Oj:wab', 'wab_load') { Oj.wab_load($json) }
|
117
115
|
end
|
118
116
|
perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
|
119
117
|
perf.run($iter)
|
120
118
|
|
119
|
+
puts '-' * 80
|
120
|
+
puts "Strict Dump Performance"
|
121
|
+
perf = Perf.new()
|
122
|
+
unless $failed.has_key?('JSON::Ext')
|
123
|
+
perf.add('JSON::Ext', 'dump') { JSON.generate($obj) }
|
124
|
+
perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
|
125
|
+
end
|
126
|
+
unless $failed.has_key?('Oj:strict')
|
127
|
+
perf.add('Oj:strict', 'dump') { Oj.dump($obj) }
|
128
|
+
end
|
129
|
+
perf.add('Yajl', 'encode') { Yajl::Encoder.encode($obj) } unless $failed.has_key?('Yajl')
|
130
|
+
perf.run($iter)
|
131
|
+
|
121
132
|
puts
|
122
133
|
puts '-' * 80
|
123
134
|
puts
|
data/test/perf_wab.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << '.'
|
5
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
$: << File.join(File.dirname(__FILE__), "../ext")
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
require 'perf'
|
10
|
+
require 'oj'
|
11
|
+
|
12
|
+
$verbose = false
|
13
|
+
$indent = 0
|
14
|
+
$iter = 20000
|
15
|
+
$with_bignum = false
|
16
|
+
$with_nums = true
|
17
|
+
$size = 0
|
18
|
+
|
19
|
+
opts = OptionParser.new
|
20
|
+
opts.on("-v", "verbose") { $verbose = true }
|
21
|
+
opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
|
22
|
+
opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
|
23
|
+
opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
|
24
|
+
opts.on("-b", "with bignum") { $with_bignum = true }
|
25
|
+
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
26
|
+
files = opts.parse(ARGV)
|
27
|
+
|
28
|
+
$obj = {
|
29
|
+
a: 'Alpha', # string
|
30
|
+
b: true, # boolean
|
31
|
+
c: 12345, # number
|
32
|
+
d: [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
|
33
|
+
e: { zero: nil, one: 1, two: 2, three: [3], four: [0, 1, 2, 3, 4] }, # hash
|
34
|
+
f: nil, # nil
|
35
|
+
h: { a: { b: { c: { d: {e: { f: { g: nil }}}}}}}, # deep hash, not that deep
|
36
|
+
i: [[[[[[[nil]]]]]]] # deep array, again, not that deep
|
37
|
+
}
|
38
|
+
$obj[:g] = 12345678901234567890123456789 if $with_bignum
|
39
|
+
|
40
|
+
Oj.default_options = { :indent => $indent, :mode => :wab }
|
41
|
+
|
42
|
+
if 0 < $size
|
43
|
+
o = $obj
|
44
|
+
$obj = []
|
45
|
+
(4 * $size).times do
|
46
|
+
$obj << o
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
$json = Oj.dump($obj)
|
51
|
+
$obj_json = Oj.dump($obj, :mode => :object)
|
52
|
+
#puts "*** size: #{$obj_json.size}"
|
53
|
+
#puts "*** #{$obj_json}"
|
54
|
+
$failed = {} # key is same as String used in tests later
|
55
|
+
|
56
|
+
def capture_error(tag, orig, load_key, dump_key, &blk)
|
57
|
+
begin
|
58
|
+
obj = blk.call(orig)
|
59
|
+
raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
|
60
|
+
rescue Exception => e
|
61
|
+
$failed[tag] = "#{e.class}: #{e.message}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Verify that all packages dump and load correctly and return the same Object as the original.
|
66
|
+
capture_error('Oj:wab', $obj, 'load', 'dump') { |o| Oj.wab_load(Oj.dump(o, :mode => :wab)) }
|
67
|
+
capture_error('Yajl', $obj, 'encode', 'parse') { |o| require 'yajl'; Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
|
68
|
+
capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
|
69
|
+
require 'json'
|
70
|
+
require 'json/ext'
|
71
|
+
JSON.generator = JSON::Ext::Generator
|
72
|
+
JSON.parser = JSON::Ext::Parser
|
73
|
+
JSON.parse(JSON.generate(o))
|
74
|
+
}
|
75
|
+
capture_error('JSON::Pure', $obj, 'generate', 'parse') { |o|
|
76
|
+
require 'json/pure'
|
77
|
+
JSON.generator = JSON::Pure::Generator
|
78
|
+
JSON.parser = JSON::Pure::Parser
|
79
|
+
JSON.parse(JSON.generate(o))
|
80
|
+
}
|
81
|
+
|
82
|
+
if $verbose
|
83
|
+
puts "json:\n#{$json}\n"
|
84
|
+
puts "object json:\n#{$obj_json}\n"
|
85
|
+
puts "Oj loaded object:\n#{Oj.wab_load($json)}\n"
|
86
|
+
puts "Yajl loaded object:\n#{Yajl::Parser.parse($json)}\n"
|
87
|
+
puts "JSON loaded object:\n#{JSON::Ext::Parser.new($json).parse}\n"
|
88
|
+
end
|
89
|
+
|
90
|
+
puts '-' * 80
|
91
|
+
puts "Wab Parse Performance"
|
92
|
+
perf = Perf.new()
|
93
|
+
unless $failed.has_key?('JSON::Ext')
|
94
|
+
perf.add('JSON::Ext', 'parse') { JSON.parse($json) }
|
95
|
+
perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
|
96
|
+
end
|
97
|
+
unless $failed.has_key?('JSON::Pure')
|
98
|
+
perf.add('JSON::Pure', 'parse') { JSON.parse($json) }
|
99
|
+
perf.before('JSON::Pure') { JSON.parser = JSON::Pure::Parser }
|
100
|
+
end
|
101
|
+
unless $failed.has_key?('Oj:wab')
|
102
|
+
perf.add('Oj:wab', 'wab_load') { Oj.wab_load($json) }
|
103
|
+
end
|
104
|
+
perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
|
105
|
+
perf.run($iter)
|
106
|
+
|
107
|
+
puts '-' * 80
|
108
|
+
puts "Wab Dump Performance"
|
109
|
+
perf = Perf.new()
|
110
|
+
unless $failed.has_key?('JSON::Ext')
|
111
|
+
perf.add('JSON::Ext', 'dump') { JSON.generate($obj) }
|
112
|
+
perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
|
113
|
+
end
|
114
|
+
unless $failed.has_key?('JSON::Pure')
|
115
|
+
perf.add('JSON::Pure', 'generate') { JSON.generate($obj) }
|
116
|
+
perf.before('JSON::Pure') { JSON.generator = JSON::Pure::Generator }
|
117
|
+
end
|
118
|
+
unless $failed.has_key?('Oj:wab')
|
119
|
+
perf.add('Oj:wab', 'dump') { Oj.dump($obj, :mode => :wab) }
|
120
|
+
end
|
121
|
+
perf.add('Yajl', 'encode') { Yajl::Encoder.encode($obj) } unless $failed.has_key?('Yajl')
|
122
|
+
perf.run($iter)
|
123
|
+
|
124
|
+
puts
|
125
|
+
puts '-' * 80
|
126
|
+
puts
|
127
|
+
|
128
|
+
unless $failed.empty?
|
129
|
+
puts "The following packages were not included for the reason listed"
|
130
|
+
$failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
|
131
|
+
end
|
data/test/prec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oj'
|
4
|
+
|
5
|
+
extras = {"locationLng" => -97.14690769100295}
|
6
|
+
|
7
|
+
Oj.default_options = {float_precision: 17}
|
8
|
+
|
9
|
+
encoded = Oj.dump(extras)
|
10
|
+
puts encoded
|
11
|
+
puts Oj.load(encoded)
|
12
|
+
|
13
|
+
require "active_record"
|
14
|
+
|
15
|
+
Oj::Rails.set_encoder()
|
16
|
+
Oj::Rails.set_decoder()
|
17
|
+
|
18
|
+
Oj.default_options = {float_precision: 17}
|
19
|
+
# Using Oj rails encoder, gets the correct value: {"locationLng":-97.14690769100295}
|
20
|
+
encoded = ActiveSupport::JSON.encode(extras)
|
21
|
+
puts encoded
|
22
|
+
puts ActiveSupport::JSON.decode(encoded)
|
23
|
+
puts Oj.load(encoded)
|
data/test/sample.rb
CHANGED
data/test/sample_json.rb
CHANGED