oj 2.18.3 → 3.13.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1324 -0
  3. data/README.md +51 -204
  4. data/RELEASE_NOTES.md +61 -0
  5. data/ext/oj/buf.h +49 -72
  6. data/ext/oj/cache.c +326 -0
  7. data/ext/oj/cache.h +21 -0
  8. data/ext/oj/cache8.c +61 -64
  9. data/ext/oj/cache8.h +12 -39
  10. data/ext/oj/circarray.c +37 -68
  11. data/ext/oj/circarray.h +16 -42
  12. data/ext/oj/code.c +221 -0
  13. data/ext/oj/code.h +40 -0
  14. data/ext/oj/compat.c +231 -107
  15. data/ext/oj/custom.c +1125 -0
  16. data/ext/oj/debug.c +132 -0
  17. data/ext/oj/dump.c +935 -2513
  18. data/ext/oj/dump.h +108 -0
  19. data/ext/oj/dump_compat.c +936 -0
  20. data/ext/oj/dump_leaf.c +164 -0
  21. data/ext/oj/dump_object.c +761 -0
  22. data/ext/oj/dump_strict.c +410 -0
  23. data/ext/oj/encode.h +7 -42
  24. data/ext/oj/encoder.c +43 -0
  25. data/ext/oj/err.c +40 -54
  26. data/ext/oj/err.h +52 -46
  27. data/ext/oj/extconf.rb +21 -30
  28. data/ext/oj/fast.c +1097 -1080
  29. data/ext/oj/intern.c +301 -0
  30. data/ext/oj/intern.h +26 -0
  31. data/ext/oj/mimic_json.c +893 -0
  32. data/ext/oj/object.c +549 -620
  33. data/ext/oj/odd.c +155 -167
  34. data/ext/oj/odd.h +37 -63
  35. data/ext/oj/oj.c +1661 -2063
  36. data/ext/oj/oj.h +341 -270
  37. data/ext/oj/parse.c +974 -737
  38. data/ext/oj/parse.h +105 -97
  39. data/ext/oj/parser.c +1526 -0
  40. data/ext/oj/parser.h +90 -0
  41. data/ext/oj/rails.c +1504 -0
  42. data/ext/oj/rails.h +18 -0
  43. data/ext/oj/reader.c +141 -163
  44. data/ext/oj/reader.h +75 -113
  45. data/ext/oj/resolve.c +45 -93
  46. data/ext/oj/resolve.h +7 -34
  47. data/ext/oj/rxclass.c +143 -0
  48. data/ext/oj/rxclass.h +26 -0
  49. data/ext/oj/saj.c +447 -511
  50. data/ext/oj/saj2.c +348 -0
  51. data/ext/oj/scp.c +91 -138
  52. data/ext/oj/sparse.c +793 -644
  53. data/ext/oj/stream_writer.c +331 -0
  54. data/ext/oj/strict.c +145 -109
  55. data/ext/oj/string_writer.c +493 -0
  56. data/ext/oj/trace.c +72 -0
  57. data/ext/oj/trace.h +28 -0
  58. data/ext/oj/usual.c +1254 -0
  59. data/ext/oj/util.c +136 -0
  60. data/ext/oj/util.h +20 -0
  61. data/ext/oj/val_stack.c +62 -70
  62. data/ext/oj/val_stack.h +95 -129
  63. data/ext/oj/validate.c +51 -0
  64. data/ext/oj/wab.c +622 -0
  65. data/lib/oj/bag.rb +1 -0
  66. data/lib/oj/easy_hash.rb +17 -8
  67. data/lib/oj/error.rb +10 -11
  68. data/lib/oj/json.rb +176 -0
  69. data/lib/oj/mimic.rb +158 -19
  70. data/lib/oj/state.rb +132 -0
  71. data/lib/oj/version.rb +2 -2
  72. data/lib/oj.rb +1 -31
  73. data/pages/Advanced.md +22 -0
  74. data/pages/Compatibility.md +25 -0
  75. data/pages/Custom.md +23 -0
  76. data/pages/Encoding.md +65 -0
  77. data/pages/JsonGem.md +94 -0
  78. data/pages/Modes.md +161 -0
  79. data/pages/Options.md +327 -0
  80. data/pages/Parser.md +309 -0
  81. data/pages/Rails.md +167 -0
  82. data/pages/Security.md +20 -0
  83. data/pages/WAB.md +13 -0
  84. data/test/activerecord/result_test.rb +32 -0
  85. data/test/activesupport4/decoding_test.rb +108 -0
  86. data/test/activesupport4/encoding_test.rb +531 -0
  87. data/test/activesupport4/test_helper.rb +41 -0
  88. data/test/activesupport5/abstract_unit.rb +45 -0
  89. data/test/activesupport5/decoding_test.rb +133 -0
  90. data/test/activesupport5/encoding_test.rb +500 -0
  91. data/test/activesupport5/encoding_test_cases.rb +98 -0
  92. data/test/activesupport5/test_helper.rb +72 -0
  93. data/test/activesupport5/time_zone_test_helpers.rb +39 -0
  94. data/test/activesupport6/abstract_unit.rb +44 -0
  95. data/test/activesupport6/decoding_test.rb +133 -0
  96. data/test/activesupport6/encoding_test.rb +507 -0
  97. data/test/activesupport6/encoding_test_cases.rb +98 -0
  98. data/test/activesupport6/test_common.rb +17 -0
  99. data/test/activesupport6/test_helper.rb +163 -0
  100. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  101. data/test/activesupport7/abstract_unit.rb +49 -0
  102. data/test/activesupport7/decoding_test.rb +125 -0
  103. data/test/activesupport7/encoding_test.rb +486 -0
  104. data/test/activesupport7/encoding_test_cases.rb +104 -0
  105. data/test/activesupport7/time_zone_test_helpers.rb +47 -0
  106. data/test/bar.rb +9 -0
  107. data/test/baz.rb +16 -0
  108. data/test/bug.rb +11 -46
  109. data/test/foo.rb +69 -16
  110. data/test/helper.rb +10 -1
  111. data/test/isolated/shared.rb +12 -8
  112. data/test/isolated/test_mimic_rails_after.rb +3 -3
  113. data/test/isolated/test_mimic_rails_before.rb +3 -3
  114. data/test/json_gem/json_addition_test.rb +216 -0
  115. data/test/json_gem/json_common_interface_test.rb +153 -0
  116. data/test/json_gem/json_encoding_test.rb +107 -0
  117. data/test/json_gem/json_ext_parser_test.rb +20 -0
  118. data/test/json_gem/json_fixtures_test.rb +35 -0
  119. data/test/json_gem/json_generator_test.rb +397 -0
  120. data/test/json_gem/json_generic_object_test.rb +90 -0
  121. data/test/json_gem/json_parser_test.rb +470 -0
  122. data/test/json_gem/json_string_matching_test.rb +42 -0
  123. data/test/json_gem/test_helper.rb +26 -0
  124. data/test/mem.rb +33 -0
  125. data/test/perf.rb +1 -1
  126. data/test/perf_compat.rb +30 -28
  127. data/test/perf_dump.rb +50 -0
  128. data/test/perf_object.rb +1 -1
  129. data/test/perf_once.rb +58 -0
  130. data/test/perf_parser.rb +189 -0
  131. data/test/perf_scp.rb +11 -10
  132. data/test/perf_strict.rb +30 -19
  133. data/test/perf_wab.rb +131 -0
  134. data/test/prec.rb +23 -0
  135. data/test/sample.rb +0 -1
  136. data/test/sample_json.rb +1 -1
  137. data/test/test_compat.rb +219 -102
  138. data/test/test_custom.rb +533 -0
  139. data/test/test_fast.rb +107 -35
  140. data/test/test_file.rb +19 -25
  141. data/test/test_generate.rb +21 -0
  142. data/test/test_hash.rb +11 -1
  143. data/test/test_integer_range.rb +72 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +357 -70
  146. data/test/test_parser.rb +27 -0
  147. data/test/test_parser_saj.rb +245 -0
  148. data/test/test_parser_usual.rb +217 -0
  149. data/test/test_rails.rb +35 -0
  150. data/test/test_saj.rb +1 -1
  151. data/test/test_scp.rb +39 -2
  152. data/test/test_strict.rb +186 -7
  153. data/test/test_various.rb +160 -774
  154. data/test/test_wab.rb +307 -0
  155. data/test/test_writer.rb +90 -2
  156. data/test/tests.rb +24 -0
  157. data/test/tests_mimic.rb +14 -0
  158. data/test/tests_mimic_addition.rb +7 -0
  159. data/test/zoo.rb +13 -0
  160. metadata +194 -56
  161. data/ext/oj/hash.c +0 -163
  162. data/ext/oj/hash.h +0 -46
  163. data/ext/oj/hash_test.c +0 -512
  164. data/test/activesupport_datetime_test.rb +0 -23
  165. data/test/bug2.rb +0 -10
  166. data/test/bug3.rb +0 -46
  167. data/test/bug_fast.rb +0 -32
  168. data/test/bug_load.rb +0 -24
  169. data/test/crash.rb +0 -111
  170. data/test/curl/curl_oj.rb +0 -46
  171. data/test/curl/get_oj.rb +0 -24
  172. data/test/curl/just_curl.rb +0 -31
  173. data/test/curl/just_oj.rb +0 -51
  174. data/test/example.rb +0 -11
  175. data/test/io.rb +0 -48
  176. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  177. data/test/mod.rb +0 -16
  178. data/test/rails.rb +0 -50
  179. data/test/russian.rb +0 -18
  180. data/test/struct.rb +0 -29
  181. data/test/test_serializer.rb +0 -59
  182. 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
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby -wW1
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  $: << '.'
4
4
  $: << '../lib'
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
@@ -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 = 50000
17
+ $iter = 50_000
18
18
  $with_bignum = false
19
- $size = 0
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)") { |i| $size = i }
26
- opts.on("-b", "with bignum") { $with_bignum = true }
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 => :compat }
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 -wW1
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| Oj.strict_load(Oj.dump(o, :mode => :strict)) }
81
- capture_error('Yajl', $obj, 'encode', 'parse') { |o| require 'yajl'; Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
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
- capture_error('JSON::Pure', $obj, 'generate', 'parse') { |o|
90
- require 'json/pure'
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
@@ -10,7 +10,6 @@ end
10
10
  require 'pp'
11
11
  require 'sample/doc'
12
12
 
13
-
14
13
  def sample_doc(size=3)
15
14
  colors = [ :black, :gray, :white, :red, :blue, :yellow, :green, :purple, :orange ]
16
15
 
data/test/sample_json.rb CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby -wW2
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  if $0 == __FILE__
4
4
  $: << '.'