oj 3.16.9 → 3.16.10

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/ext/oj/fast.c +3 -6
  4. data/ext/oj/mimic_json.c +3 -6
  5. data/ext/oj/oj.c +2 -4
  6. data/ext/oj/parse.c +15 -5
  7. data/ext/oj/parser.c +1 -1
  8. data/ext/oj/parser.h +2 -0
  9. data/ext/oj/rails.c +1 -2
  10. data/ext/oj/saj.c +3 -6
  11. data/ext/oj/scp.c +3 -6
  12. data/ext/oj/stream_writer.c +1 -7
  13. data/ext/oj/strict.c +2 -4
  14. data/ext/oj/string_writer.c +1 -3
  15. data/lib/oj/version.rb +1 -1
  16. metadata +3 -98
  17. data/test/_test_active.rb +0 -75
  18. data/test/_test_active_mimic.rb +0 -95
  19. data/test/_test_mimic_rails.rb +0 -123
  20. data/test/activerecord/result_test.rb +0 -31
  21. data/test/activesupport6/abstract_unit.rb +0 -44
  22. data/test/activesupport6/decoding_test.rb +0 -133
  23. data/test/activesupport6/encoding_test.rb +0 -542
  24. data/test/activesupport6/encoding_test_cases.rb +0 -98
  25. data/test/activesupport6/test_common.rb +0 -17
  26. data/test/activesupport6/test_helper.rb +0 -163
  27. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  28. data/test/activesupport7/abstract_unit.rb +0 -52
  29. data/test/activesupport7/decoding_test.rb +0 -125
  30. data/test/activesupport7/encoding_test.rb +0 -536
  31. data/test/activesupport7/encoding_test_cases.rb +0 -104
  32. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  33. data/test/files.rb +0 -29
  34. data/test/foo.rb +0 -26
  35. data/test/helper.rb +0 -39
  36. data/test/isolated/shared.rb +0 -309
  37. data/test/isolated/test_mimic_after.rb +0 -13
  38. data/test/isolated/test_mimic_alone.rb +0 -12
  39. data/test/isolated/test_mimic_as_json.rb +0 -45
  40. data/test/isolated/test_mimic_before.rb +0 -13
  41. data/test/isolated/test_mimic_define.rb +0 -28
  42. data/test/isolated/test_mimic_rails_after.rb +0 -22
  43. data/test/isolated/test_mimic_rails_before.rb +0 -21
  44. data/test/isolated/test_mimic_redefine.rb +0 -15
  45. data/test/json_gem/json_addition_test.rb +0 -216
  46. data/test/json_gem/json_common_interface_test.rb +0 -155
  47. data/test/json_gem/json_encoding_test.rb +0 -107
  48. data/test/json_gem/json_ext_parser_test.rb +0 -21
  49. data/test/json_gem/json_fixtures_test.rb +0 -36
  50. data/test/json_gem/json_generator_test.rb +0 -413
  51. data/test/json_gem/json_generic_object_test.rb +0 -90
  52. data/test/json_gem/json_parser_test.rb +0 -477
  53. data/test/json_gem/json_string_matching_test.rb +0 -42
  54. data/test/json_gem/test_helper.rb +0 -30
  55. data/test/mem.rb +0 -34
  56. data/test/perf.rb +0 -102
  57. data/test/perf_compat.rb +0 -128
  58. data/test/perf_dump.rb +0 -50
  59. data/test/perf_fast.rb +0 -162
  60. data/test/perf_file.rb +0 -62
  61. data/test/perf_object.rb +0 -134
  62. data/test/perf_once.rb +0 -59
  63. data/test/perf_parser.rb +0 -183
  64. data/test/perf_saj.rb +0 -101
  65. data/test/perf_scp.rb +0 -140
  66. data/test/perf_simple.rb +0 -289
  67. data/test/perf_strict.rb +0 -137
  68. data/test/perf_wab.rb +0 -129
  69. data/test/prec.rb +0 -23
  70. data/test/sample/change.rb +0 -13
  71. data/test/sample/dir.rb +0 -18
  72. data/test/sample/doc.rb +0 -35
  73. data/test/sample/file.rb +0 -47
  74. data/test/sample/group.rb +0 -15
  75. data/test/sample/hasprops.rb +0 -15
  76. data/test/sample/layer.rb +0 -11
  77. data/test/sample/line.rb +0 -20
  78. data/test/sample/oval.rb +0 -10
  79. data/test/sample/rect.rb +0 -9
  80. data/test/sample/shape.rb +0 -34
  81. data/test/sample/text.rb +0 -19
  82. data/test/sample.rb +0 -54
  83. data/test/sample_json.rb +0 -37
  84. data/test/test_compat.rb +0 -567
  85. data/test/test_custom.rb +0 -555
  86. data/test/test_debian.rb +0 -50
  87. data/test/test_fast.rb +0 -526
  88. data/test/test_file.rb +0 -250
  89. data/test/test_gc.rb +0 -60
  90. data/test/test_generate.rb +0 -21
  91. data/test/test_hash.rb +0 -39
  92. data/test/test_integer_range.rb +0 -72
  93. data/test/test_null.rb +0 -376
  94. data/test/test_object.rb +0 -1030
  95. data/test/test_parser.rb +0 -11
  96. data/test/test_parser_debug.rb +0 -27
  97. data/test/test_parser_saj.rb +0 -337
  98. data/test/test_parser_usual.rb +0 -255
  99. data/test/test_rails.rb +0 -35
  100. data/test/test_saj.rb +0 -188
  101. data/test/test_scp.rb +0 -431
  102. data/test/test_strict.rb +0 -441
  103. data/test/test_various.rb +0 -801
  104. data/test/test_wab.rb +0 -311
  105. data/test/test_writer.rb +0 -396
  106. data/test/tests.rb +0 -33
  107. data/test/tests_mimic.rb +0 -23
  108. data/test/tests_mimic_addition.rb +0 -16
data/test/perf_parser.rb DELETED
@@ -1,183 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << '.'
5
- $LOAD_PATH << File.join(__dir__, '../lib')
6
- $LOAD_PATH << File.join(__dir__, '../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
- opts.parse(ARGV)
29
-
30
- $obj = {
31
- 'a' => 'Alpha', # string
32
- 'b' => true, # boolean
33
- 'c' => 12_345, # number
34
- 'd' => [ true, [false, [-123_456_789, 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'] = 12_345_678_901_234_567_890_123_456_789 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
- Oj.default_options = if $cache_keys
54
- {cache_keys: true, cache_str: 6, symbol_keys: $symbol_keys}
55
- else
56
- {cache_keys: false, cache_str: -1, symbol_keys: $symbol_keys}
57
- end
58
- JSON.parser = JSON::Ext::Parser
59
-
60
- class AllSaj
61
-
62
- def hash_start(key)
63
- end
64
-
65
- def hash_end(key)
66
- end
67
-
68
- def array_start(key)
69
- end
70
-
71
- def array_end(key)
72
- end
73
-
74
- def add_value(value, key)
75
- end
76
- end # AllSaj
77
-
78
- no_handler = Object.new()
79
- all_handler = AllSaj.new()
80
-
81
- if $verbose
82
- puts "json:\n#{$json}\n"
83
- end
84
-
85
- ### Validate ######################
86
- p_val = Oj::Parser.new(:validate)
87
-
88
- puts '-' * 80
89
- puts 'Validate Performance'
90
- perf = Perf.new()
91
- perf.add('Oj::Parser.validate', 'none') { p_val.parse($json) }
92
- perf.add('Oj::Saj.none', 'none') { Oj.saj_parse(no_handler, $json) }
93
- perf.run($iter)
94
-
95
- ### SAJ ######################
96
- p_all = Oj::Parser.new(:saj)
97
- p_all.handler = all_handler
98
- p_all.cache_keys = $cache_keys
99
- p_all.cache_strings = 6
100
-
101
- puts '-' * 80
102
- puts 'Parse Callback Performance'
103
- perf = Perf.new()
104
- perf.add('Oj::Parser.saj', 'all') { p_all.parse($json) }
105
- perf.add('Oj::Saj.all', 'all') { Oj.saj_parse(all_handler, $json) }
106
- perf.run($iter)
107
-
108
- ### Usual ######################
109
- p_usual = Oj::Parser.new(:usual)
110
- p_usual.cache_keys = $cache_keys
111
- p_usual.cache_strings = ($cache_keys ? 6 : 0)
112
- p_usual.symbol_keys = $symbol_keys
113
-
114
- puts '-' * 80
115
- puts 'Parse Usual Performance'
116
- perf = Perf.new()
117
- perf.add('Oj::Parser.usual', '') { p_usual.parse($json) }
118
- perf.add('Oj::strict_load', '') { Oj.strict_load($json) }
119
- perf.add('JSON::Ext', 'parse') { JSON.parse($json) }
120
- perf.run($iter)
121
-
122
- ### Usual Objects ######################
123
-
124
- # Original Oj follows the JSON gem for creating objects which uses the class
125
- # json_create(arg) method. Oj::Parser in usual mode supprts the same but also
126
- # handles populating the object variables directly which is faster.
127
-
128
- class Stuff
129
- attr_accessor :alpha, :bravo, :charlie, :delta, :echo, :foxtrot, :golf, :hotel, :india, :juliet
130
-
131
- def self.json_create(arg)
132
- obj = new
133
- obj.alpha = arg['alpha']
134
- obj.bravo = arg['bravo']
135
- obj.charlie = arg['charlie']
136
- obj.delta = arg['delta']
137
- obj.echo = arg['echo']
138
- obj.foxtrot = arg['foxtrot']
139
- obj.golf = arg['golf']
140
- obj.hotel = arg['hotel']
141
- obj.india = arg['india']
142
- obj.juliet = arg['juliet']
143
- obj
144
- end
145
- end
146
-
147
- $obj_json = %|{
148
- "alpha": [0, 1,2,3,4,5,6,7,8,9],
149
- "bravo": true,
150
- "charlie": 123,
151
- "delta": "some string",
152
- "echo": null,
153
- "^": "Stuff",
154
- "foxtrot": false,
155
- "golf": "gulp",
156
- "hotel": {"x": true, "y": false},
157
- "india": [null, true, 123],
158
- "juliet": "junk"
159
- }|
160
-
161
- p_usual = Oj::Parser.new(:usual)
162
- p_usual.cache_keys = $cache_keys
163
- p_usual.cache_strings = ($cache_keys ? 6 : 0)
164
- p_usual.symbol_keys = $symbol_keys
165
- p_usual.create_id = '^'
166
- p_usual.class_cache = true
167
- p_usual.ignore_json_create = true
168
-
169
- JSON.create_id = '^'
170
-
171
- puts '-' * 80
172
- puts 'Parse Usual Object Performance'
173
- perf = Perf.new()
174
- perf.add('Oj::Parser.usual', '') { p_usual.parse($obj_json) }
175
- perf.add('Oj::compat_load', '') { Oj.compat_load($obj_json) }
176
- perf.add('JSON::Ext', 'parse') { JSON.parse($obj_json) }
177
-
178
- perf.run($iter)
179
-
180
- unless $failed.empty?
181
- puts 'The following packages were not included for the reason listed'
182
- $failed.each { |tag, msg| puts "***** #{tag}: #{msg}" }
183
- end
data/test/perf_saj.rb DELETED
@@ -1,101 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << '.'
5
- $LOAD_PATH << File.join(__dir__, '../lib')
6
- $LOAD_PATH << File.join(__dir__, '../ext')
7
-
8
- require 'optparse'
9
- # require 'yajl'
10
- require 'perf'
11
- require 'json'
12
- require 'json/ext'
13
- require 'oj'
14
-
15
- @verbose = false
16
- @indent = 0
17
- @iter = 10_000
18
- @gets = 0
19
- @fetch = false
20
- @write = false
21
- @read = false
22
-
23
- opts = OptionParser.new
24
- opts.on('-v', 'verbose') { @verbose = true }
25
- opts.on('-c', '--count [Int]', Integer, 'iterations') { |i| @iter = i }
26
- opts.on('-i', '--indent [Int]', Integer, 'indentation') { |i| @indent = i }
27
- opts.on('-g', '--gets [Int]', Integer, 'number of gets') { |i| @gets = i }
28
- opts.on('-f', 'fetch') { @fetch = true }
29
- opts.on('-w', 'write') { @write = true }
30
- opts.on('-r', 'read') { @read = true }
31
- opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) }
32
- opts.parse(ARGV)
33
-
34
- class AllSaj < Oj::Saj
35
- def hash_start(key)
36
- end
37
-
38
- def hash_end(key)
39
- end
40
-
41
- def array_start(key)
42
- end
43
-
44
- def array_end(key)
45
- end
46
-
47
- def add_value(value, key)
48
- end
49
- end # AllSaj
50
-
51
- class NoSaj < Oj::Saj
52
- end # NoSaj
53
-
54
- saj_handler = AllSaj.new()
55
- no_saj = NoSaj.new()
56
-
57
- @obj = {
58
- 'a' => 'Alpha', # string
59
- 'b' => true, # boolean
60
- 'c' => 12_345, # number
61
- 'd' => [ true, [false, {'12345' => 12_345, 'nil' => nil}, 3.967, { 'x' => 'something', 'y' => false, 'z' => true}, nil]], # mix it up array
62
- 'e' => { 'one' => 1, 'two' => 2 }, # hash
63
- 'f' => nil, # nil
64
- 'g' => 12_345_678_901_234_567_890_123_456_789, # big number
65
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
66
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
67
- }
68
-
69
- Oj.default_options = { :indent => @indent, :mode => :compat }
70
-
71
- @json = Oj.dump(@obj)
72
- @failed = {} # key is same as String used in tests later
73
-
74
- def capture_error(tag, orig, load_key, dump_key, &blk)
75
- obj = blk.call(orig)
76
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
77
- rescue Exception => e
78
- @failed[tag] = "#{e.class}: #{e.message}"
79
- end
80
-
81
- # Verify that all packages dump and load correctly and return the same Object as the original.
82
- # capture_error('Yajl', @obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
83
- capture_error('JSON::Ext', @obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
84
-
85
- if @verbose
86
- puts "json:\n#{@json}\n"
87
- end
88
-
89
- puts '-' * 80
90
- puts 'Parse Performance'
91
- perf = Perf.new()
92
- perf.add('Oj::Saj', 'all') { Oj.saj_parse(saj_handler, @json) }
93
- perf.add('Oj::Saj', 'none') { Oj.saj_parse(no_saj, @json) }
94
- # perf.add('Yajl', 'parse') { Yajl::Parser.parse(@json) } unless @failed.has_key?('Yajl')
95
- perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new(@json).parse } unless @failed.key?('JSON::Ext')
96
- perf.run(@iter)
97
-
98
- unless @failed.empty?
99
- puts 'The following packages were not included for the reason listed'
100
- @failed.each { |tag, msg| puts "***** #{tag}: #{msg}" }
101
- end
data/test/perf_scp.rb DELETED
@@ -1,140 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << '.'
5
- $LOAD_PATH << File.join(__dir__, '../lib')
6
- $LOAD_PATH << File.join(__dir__, '../ext')
7
-
8
- require 'optparse'
9
- # require 'yajl'
10
- require 'perf'
11
- require 'json'
12
- require 'json/ext'
13
- require 'oj'
14
-
15
- @verbose = false
16
- @indent = 0
17
- @iter = 50_000
18
- @with_bignum = false
19
- @size = 1
20
-
21
- opts = OptionParser.new
22
- opts.on('-v', 'verbose') { @verbose = true }
23
- opts.on('-c', '--count [Int]', Integer, 'iterations') { |i| @iter = i }
24
- opts.on('-i', '--indent [Int]', Integer, 'indentation') { |i| @indent = i }
25
- opts.on('-s', '--size [Int]', Integer, 'size (~Kbytes)') { |i| @size = i }
26
- opts.on('-b', 'with bignum') { @with_bignum = true }
27
- opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) }
28
- opts.parse(ARGV)
29
-
30
- @obj = {
31
- 'a' => 'Alpha', # string
32
- 'b' => true, # boolean
33
- 'c' => 12_345, # number
34
- 'd' => [ true, [false, [-123_456_789, nil], 3.9676, ['Something else.', false], 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'] = 12_345_678_901_234_567_890_123_456_789 if @with_bignum
41
-
42
- if 0 < @size
43
- ob = @obj
44
- @obj = []
45
- (4 * @size).times do
46
- @obj << ob
47
- end
48
- end
49
-
50
- Oj.default_options = { :indent => @indent, :mode => :strict, cache_keys: true, cache_str: 5 }
51
-
52
- @json = Oj.dump(@obj)
53
- @failed = {} # key is same as String used in tests later
54
-
55
- class AllSaj < Oj::Saj
56
- def hash_start(key)
57
- end
58
-
59
- def hash_end(key)
60
- end
61
-
62
- def array_start(key)
63
- end
64
-
65
- def array_end(key)
66
- end
67
-
68
- def add_value(value, key)
69
- end
70
- end # AllSaj
71
-
72
- class NoSaj < Oj::Saj
73
- end # NoSaj
74
-
75
- class NoHandler < Oj::ScHandler
76
- end # NoHandler
77
-
78
- class AllHandler < Oj::ScHandler
79
- def hash_start
80
- nil
81
- end
82
-
83
- def hash_end
84
- end
85
-
86
- def array_start
87
- nil
88
- end
89
-
90
- def array_end
91
- end
92
-
93
- def add_value(value)
94
- end
95
-
96
- def hash_set(h, key, value)
97
- end
98
-
99
- def array_append(a, value)
100
- end
101
-
102
- end # AllHandler
103
-
104
- saj_handler = AllSaj.new()
105
- no_saj = NoSaj.new()
106
-
107
- sc_handler = AllHandler.new()
108
- no_handler = NoHandler.new()
109
-
110
- def capture_error(tag, orig, load_key, dump_key, &blk)
111
- obj = blk.call(orig)
112
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
113
- rescue Exception => e
114
- @failed[tag] = "#{e.class}: #{e.message}"
115
- end
116
-
117
- # Verify that all packages dump and load correctly and return the same Object as the original.
118
- # capture_error('Yajl', @obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
119
- capture_error('JSON::Ext', @obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
120
-
121
- if @verbose
122
- puts "json:\n#{@json}\n"
123
- end
124
-
125
- puts '-' * 80
126
- puts 'Parse Performance'
127
- perf = Perf.new()
128
- perf.add('Oj::Saj.all', 'all') { Oj.saj_parse(saj_handler, @json) }
129
- perf.add('Oj::Saj.none', 'none') { Oj.saj_parse(no_saj, @json) }
130
- perf.add('Oj::Scp.all', 'all') { Oj.sc_parse(sc_handler, @json) }
131
- perf.add('Oj::Scp.none', 'none') { Oj.sc_parse(no_handler, @json) }
132
- perf.add('Oj::load', 'none') { Oj.wab_load(@json) }
133
- # perf.add('Yajl', 'parse') { Yajl::Parser.parse(@json) } unless @failed.has_key?('Yajl')
134
- perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new(@json).parse } unless @failed.key?('JSON::Ext')
135
- perf.run(@iter)
136
-
137
- unless @failed.empty?
138
- puts 'The following packages were not included for the reason listed'
139
- @failed.each { |tag, msg| puts "***** #{tag}: #{msg}" }
140
- end
data/test/perf_simple.rb DELETED
@@ -1,289 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << File.join(__dir__, '../lib')
5
- $LOAD_PATH << File.join(__dir__, '../ext')
6
-
7
- require 'optparse'
8
- require 'yajl'
9
- require 'json'
10
- require 'json/pure'
11
- require 'json/ext'
12
- require 'msgpack'
13
- require 'oj'
14
- require 'ox'
15
-
16
- class Jazz
17
- def initialize
18
- @boolean = true
19
- @number = 58
20
- @string = 'A string'
21
- @array = [true, false, nil]
22
- @hash = { 'one' => 1, 'two' => 2 }
23
- end
24
-
25
- def to_json(*_args)
26
- %{
27
- { "boolean":#{@boolean},
28
- "number":#{@number},
29
- "string":#{@string},
30
- "array":#{@array},
31
- "hash":#{@hash},
32
- }
33
- }
34
- end
35
-
36
- def to_hash
37
- { 'boolean' => @boolean,
38
- 'number' => @number,
39
- 'string' => @string,
40
- 'array' => @array,
41
- 'hash' => @hash,
42
- }
43
- end
44
-
45
- def to_msgpack(out='')
46
- to_hash().to_msgpack(out)
47
- end
48
- end
49
-
50
- $indent = 2
51
- $iter = 10_000
52
- $with_object = true
53
- $with_bignum = true
54
- $with_nums = true
55
-
56
- opts = OptionParser.new
57
- opts.on('-c', '--count [Int]', Integer, 'iterations') { |i| $iter = i }
58
- opts.on('-i', '--indent [Int]', Integer, 'indentation') { |i| $indent = i }
59
- opts.on('-o', 'without objects') { $with_object = false }
60
- opts.on('-b', 'without bignum') { $with_bignum = false }
61
- opts.on('-n', 'without numbers') { $with_nums = false }
62
- opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) }
63
- opts.parse(ARGV)
64
-
65
- if $with_nums
66
- obj = {
67
- 'a' => 'Alpha',
68
- 'b' => true,
69
- 'c' => 12_345,
70
- 'd' => [ true, [false, [12_345, nil], 3.967, ['something', false], nil]],
71
- 'e' => { 'one' => 1, 'two' => 2 },
72
- 'f' => nil,
73
- }
74
- obj['g'] = Jazz.new() if $with_object
75
- obj['h'] = 12_345_678_901_234_567_890_123_456_789 if $with_bignum
76
- else
77
- obj = {
78
- 'a' => 'Alpha',
79
- 'b' => true,
80
- 'c' => '12345',
81
- 'd' => [ true, [false, ['12345', nil], '3.967', ['something', false], nil]],
82
- 'e' => { 'one' => '1', 'two' => '2' },
83
- 'f' => nil,
84
- }
85
- end
86
-
87
- Oj.default_options = { :indent => $indent, :mode => :object }
88
-
89
- s = Oj.dump(obj)
90
-
91
- xml = Ox.dump(obj, :indent => $indent)
92
-
93
- puts
94
-
95
- # Put Oj in strict mode so it only create JSON native types instead of the
96
- # original Ruby Objects. None of the other packages other than Ox support
97
- # Object recreation so no need for Oj to do it in the performance tests.
98
- Oj.default_options = { :mode => :strict }
99
- parse_results = { :oj => 0.0, :yajl => 0.0, :msgpack => 0.0, :pure => 0.0, :ext => 0.0, :ox => 0.0 }
100
-
101
- start = Time.now
102
- $iter.times do
103
- Oj.load(s)
104
- end
105
- dt = Time.now - start
106
- base_dt = dt
107
- parse_results[:oj] = dt
108
- puts '%d Oj.load()s in %0.3f seconds or %0.1f loads/msec' % [$iter, dt, $iter/dt/1000.0]
109
-
110
- start = Time.now
111
- $iter.times do
112
- Yajl::Parser.parse(s)
113
- end
114
- dt = Time.now - start
115
- if base_dt < dt
116
- base_dt = dt
117
- base_name = 'Yajl'
118
- end
119
- parse_results[:yajl] = dt
120
- puts '%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parses/msec' % [$iter, dt, $iter/dt/1000.0]
121
-
122
- begin
123
- JSON.parser = JSON::Ext::Parser
124
- start = Time.now
125
- $iter.times do
126
- JSON.parse(s)
127
- end
128
- dt = Time.now - start
129
- if base_dt < dt
130
- base_dt = dt
131
- base_name = 'JSON::Ext'
132
- end
133
- parse_results[:ext] = dt
134
- puts '%d JSON::Ext::Parser parse()s in %0.3f seconds or %0.1f parses/msec' % [$iter, dt, $iter/dt/1000.0]
135
- rescue Exception => e
136
- puts "JSON::Ext failed: #{e.class}: #{e.message}"
137
- end
138
-
139
- begin
140
- JSON.parser = JSON::Pure::Parser
141
- start = Time.now
142
- $iter.times do
143
- JSON.parse(s)
144
- end
145
- dt = Time.now - start
146
- if base_dt < dt
147
- base_dt = dt
148
- base_name = 'JSON::Pure'
149
- end
150
- parse_results[:pure] = dt
151
- puts '%d JSON::Pure::Parser parse()s in %0.3f seconds or %0.1f parses/msec' % [$iter, dt, $iter/dt/1000.0]
152
- rescue Exception => e
153
- puts "JSON::Pure failed: #{e.class}: #{e.message}"
154
- end
155
-
156
- begin
157
- mp = MessagePack.pack(obj)
158
- start = Time.now
159
- $iter.times do
160
- MessagePack.unpack(mp)
161
- end
162
- dt = Time.now - start
163
- if base_dt < dt
164
- base_dt = dt
165
- base_name = 'MessagePack'
166
- end
167
- parse_results[:msgpack] = dt
168
- puts '%d MessagePack.unpack()s in %0.3f seconds or %0.1f packs/msec' % [$iter, dt, $iter/dt/1000.0]
169
- rescue Exception => e
170
- puts "MessagePack failed: #{e.class}: #{e.message}"
171
- end
172
-
173
- start = Time.now
174
- $iter.times do
175
- Ox.load(xml)
176
- end
177
- dt = Time.now - start
178
- parse_results[:ox] = dt
179
- puts '%d Ox.load()s in %0.3f seconds or %0.1f loads/msec' % [$iter, dt, $iter/dt/1000.0]
180
-
181
- puts 'Parser results:'
182
- puts "gem seconds parses/msec X faster than #{base_name} (higher is better)"
183
- parse_results.each do |name, dt2|
184
- if dt2 <= 0.0
185
- puts "#{name} failed to generate JSON"
186
- next
187
- end
188
- puts '%-7s %6.3f %5.1f %4.1f' % [name, dt2, $iter/dt/1000.0, base_dt/dt2]
189
- end
190
-
191
- puts
192
-
193
- # Back to object mode for best performance when dumping.
194
- Oj.default_options = { :indent => $indent, :mode => :object }
195
-
196
- start = Time.now
197
- $iter.times do
198
- Oj.dump(obj)
199
- end
200
- dt = Time.now - start
201
- base_dt = dt
202
- base_name = 'Oj'
203
- parse_results[:oj] = dt
204
- puts '%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec' % [$iter, dt, $iter/dt/1000.0]
205
-
206
- start = Time.now
207
- $iter.times do
208
- Yajl::Encoder.encode(obj)
209
- end
210
- dt = Time.now - start
211
- if base_dt < dt
212
- base_dt = dt
213
- base_name = 'Yajl'
214
- end
215
- parse_results[:yajl] = dt
216
- puts '%d Yajl::Encoder.encode()s in %0.3f seconds or %0.1f encodes/msec' % [$iter, dt, $iter/dt/1000.0]
217
-
218
- begin
219
- JSON.parser = JSON::Ext::Parser
220
- start = Time.now
221
- $iter.times do
222
- JSON.generate(obj)
223
- end
224
- dt = Time.now - start
225
- if base_dt < dt
226
- base_dt = dt
227
- base_name = 'JSON::Ext'
228
- end
229
- parse_results[:pure] = dt
230
- puts '%d JSON::Ext generate()s in %0.3f seconds or %0.1f generates/msec' % [$iter, dt, $iter/dt/1000.0]
231
- rescue Exception => e
232
- parse_results[:ext] = 0.0
233
- puts "JSON::Ext failed: #{e.class}: #{e.message}"
234
- end
235
-
236
- begin
237
- JSON.parser = JSON::Pure::Parser
238
- start = Time.now
239
- $iter.times do
240
- JSON.generate(obj)
241
- end
242
- dt = Time.now - start
243
- if base_dt < dt
244
- base_dt = dt
245
- base_name = 'JSON::Pure'
246
- end
247
- parse_results[:pure] = dt
248
- puts '%d JSON::Pure generate()s in %0.3f seconds or %0.1f generates/msec' % [$iter, dt, $iter/dt/1000.0]
249
- rescue Exception => e
250
- parse_results[:pure] = 0.0
251
- puts "JSON::Pure failed: #{e.class}: #{e.message}"
252
- end
253
-
254
- begin
255
- start = Time.now
256
- $iter.times do
257
- MessagePack.pack(obj)
258
- end
259
- dt = Time.now - start
260
- if base_dt < dt
261
- base_dt = dt
262
- base_name = 'MessagePack'
263
- end
264
- parse_results[:msgpack] = dt
265
- puts '%d Msgpack()s in %0.3f seconds or %0.1f unpacks/msec' % [$iter, dt, $iter/dt/1000.0]
266
- rescue Exception => e
267
- parse_results[:msgpack] = 0.0
268
- puts "MessagePack failed: #{e.class}: #{e.message}"
269
- end
270
-
271
- start = Time.now
272
- $iter.times do
273
- Ox.dump(obj)
274
- end
275
- dt = Time.now - start
276
- parse_results[:ox] = dt
277
- puts '%d Ox.dump()s in %0.3f seconds or %0.1f dumps/msec' % [$iter, dt, $iter/dt/1000.0]
278
-
279
- puts 'Parser results:'
280
- puts "gem seconds dumps/msec X faster than #{base_name} (higher is better)"
281
- parse_results.each do |name, dt2|
282
- if dt2 <= 0.0
283
- puts "#{name} failed to generate JSON"
284
- next
285
- end
286
- puts '%-7s %6.3f %5.1f %4.1f' % [name, dt2, $iter/dt/1000.0, base_dt/dt2]
287
- end
288
-
289
- puts