oj 3.13.23 → 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 (178) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +2 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +26 -59
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +103 -53
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -7
  25. data/ext/oj/fast.c +63 -98
  26. data/ext/oj/intern.c +62 -47
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +54 -38
  31. data/ext/oj/object.c +33 -43
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +245 -216
  35. data/ext/oj/oj.h +83 -81
  36. data/ext/oj/parse.c +109 -153
  37. data/ext/oj/parse.h +21 -24
  38. data/ext/oj/parser.c +80 -67
  39. data/ext/oj/parser.h +9 -8
  40. data/ext/oj/rails.c +71 -94
  41. data/ext/oj/reader.c +9 -14
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +13 -15
  47. data/ext/oj/saj2.c +37 -49
  48. data/ext/oj/saj2.h +1 -1
  49. data/ext/oj/scp.c +6 -20
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +46 -48
  52. data/ext/oj/strict.c +22 -56
  53. data/ext/oj/string_writer.c +64 -40
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -114
  56. data/ext/oj/usual.h +7 -6
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +13 -2
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +7 -7
  67. data/lib/oj/schandler.rb +5 -4
  68. data/lib/oj/state.rb +8 -5
  69. data/lib/oj/version.rb +1 -2
  70. data/lib/oj.rb +2 -0
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +4 -0
  73. metadata +46 -121
  74. data/test/_test_active.rb +0 -76
  75. data/test/_test_active_mimic.rb +0 -96
  76. data/test/_test_mimic_rails.rb +0 -126
  77. data/test/activerecord/result_test.rb +0 -32
  78. data/test/activesupport4/decoding_test.rb +0 -108
  79. data/test/activesupport4/encoding_test.rb +0 -531
  80. data/test/activesupport4/test_helper.rb +0 -41
  81. data/test/activesupport5/abstract_unit.rb +0 -45
  82. data/test/activesupport5/decoding_test.rb +0 -133
  83. data/test/activesupport5/encoding_test.rb +0 -500
  84. data/test/activesupport5/encoding_test_cases.rb +0 -98
  85. data/test/activesupport5/test_helper.rb +0 -72
  86. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  87. data/test/activesupport6/abstract_unit.rb +0 -44
  88. data/test/activesupport6/decoding_test.rb +0 -133
  89. data/test/activesupport6/encoding_test.rb +0 -507
  90. data/test/activesupport6/encoding_test_cases.rb +0 -98
  91. data/test/activesupport6/test_common.rb +0 -17
  92. data/test/activesupport6/test_helper.rb +0 -163
  93. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  94. data/test/activesupport7/abstract_unit.rb +0 -49
  95. data/test/activesupport7/decoding_test.rb +0 -125
  96. data/test/activesupport7/encoding_test.rb +0 -486
  97. data/test/activesupport7/encoding_test_cases.rb +0 -104
  98. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  99. data/test/bar.rb +0 -11
  100. data/test/baz.rb +0 -16
  101. data/test/bug.rb +0 -16
  102. data/test/files.rb +0 -29
  103. data/test/foo.rb +0 -77
  104. data/test/helper.rb +0 -42
  105. data/test/isolated/shared.rb +0 -308
  106. data/test/isolated/test_mimic_after.rb +0 -13
  107. data/test/isolated/test_mimic_alone.rb +0 -12
  108. data/test/isolated/test_mimic_as_json.rb +0 -45
  109. data/test/isolated/test_mimic_before.rb +0 -13
  110. data/test/isolated/test_mimic_define.rb +0 -28
  111. data/test/isolated/test_mimic_rails_after.rb +0 -22
  112. data/test/isolated/test_mimic_rails_before.rb +0 -21
  113. data/test/isolated/test_mimic_redefine.rb +0 -15
  114. data/test/json_gem/json_addition_test.rb +0 -216
  115. data/test/json_gem/json_common_interface_test.rb +0 -153
  116. data/test/json_gem/json_encoding_test.rb +0 -107
  117. data/test/json_gem/json_ext_parser_test.rb +0 -20
  118. data/test/json_gem/json_fixtures_test.rb +0 -35
  119. data/test/json_gem/json_generator_test.rb +0 -396
  120. data/test/json_gem/json_generic_object_test.rb +0 -90
  121. data/test/json_gem/json_parser_test.rb +0 -477
  122. data/test/json_gem/json_string_matching_test.rb +0 -42
  123. data/test/json_gem/test_helper.rb +0 -30
  124. data/test/mem.rb +0 -33
  125. data/test/perf.rb +0 -107
  126. data/test/perf_compat.rb +0 -130
  127. data/test/perf_dump.rb +0 -50
  128. data/test/perf_fast.rb +0 -164
  129. data/test/perf_file.rb +0 -64
  130. data/test/perf_object.rb +0 -138
  131. data/test/perf_once.rb +0 -58
  132. data/test/perf_parser.rb +0 -189
  133. data/test/perf_saj.rb +0 -109
  134. data/test/perf_scp.rb +0 -152
  135. data/test/perf_simple.rb +0 -287
  136. data/test/perf_strict.rb +0 -139
  137. data/test/perf_wab.rb +0 -131
  138. data/test/prec.rb +0 -23
  139. data/test/sample/change.rb +0 -14
  140. data/test/sample/dir.rb +0 -19
  141. data/test/sample/doc.rb +0 -36
  142. data/test/sample/file.rb +0 -48
  143. data/test/sample/group.rb +0 -16
  144. data/test/sample/hasprops.rb +0 -16
  145. data/test/sample/layer.rb +0 -12
  146. data/test/sample/line.rb +0 -20
  147. data/test/sample/oval.rb +0 -10
  148. data/test/sample/rect.rb +0 -10
  149. data/test/sample/shape.rb +0 -35
  150. data/test/sample/text.rb +0 -20
  151. data/test/sample.rb +0 -54
  152. data/test/sample_json.rb +0 -37
  153. data/test/test_compat.rb +0 -540
  154. data/test/test_custom.rb +0 -544
  155. data/test/test_debian.rb +0 -53
  156. data/test/test_fast.rb +0 -530
  157. data/test/test_file.rb +0 -255
  158. data/test/test_gc.rb +0 -60
  159. data/test/test_generate.rb +0 -21
  160. data/test/test_hash.rb +0 -39
  161. data/test/test_integer_range.rb +0 -72
  162. data/test/test_null.rb +0 -376
  163. data/test/test_object.rb +0 -1025
  164. data/test/test_parser.rb +0 -11
  165. data/test/test_parser_debug.rb +0 -27
  166. data/test/test_parser_saj.rb +0 -335
  167. data/test/test_parser_usual.rb +0 -217
  168. data/test/test_rails.rb +0 -35
  169. data/test/test_saj.rb +0 -186
  170. data/test/test_scp.rb +0 -431
  171. data/test/test_strict.rb +0 -435
  172. data/test/test_various.rb +0 -752
  173. data/test/test_wab.rb +0 -309
  174. data/test/test_writer.rb +0 -380
  175. data/test/tests.rb +0 -33
  176. data/test/tests_mimic.rb +0 -23
  177. data/test/tests_mimic_addition.rb +0 -16
  178. data/test/zoo.rb +0 -13
data/test/perf_compat.rb DELETED
@@ -1,130 +0,0 @@
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
- $size = 0
16
-
17
- opts = OptionParser.new
18
- opts.on("-v", "verbose") { $verbose = true }
19
- opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
20
- opts.on("-i", "--indent [Int]", Integer, "indentation") { |i| $indent = i }
21
- opts.on("-s", "--size [Int]", Integer, "size (~Kbytes)") { |i| $size = i }
22
- opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
23
- files = opts.parse(ARGV)
24
-
25
- def capture_error(tag, orig, load_key, dump_key, &blk)
26
- begin
27
- obj = blk.call(orig)
28
- puts obj unless orig == obj
29
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
30
- rescue Exception => e
31
- $failed[tag] = "#{e.class}: #{e.message}"
32
- end
33
- end
34
-
35
- # Verify that all packages dump and load correctly and return the same Object as the original.
36
- capture_error('Oj:compat', $obj, 'load', 'dump') { |o| Oj.compat_load(Oj.dump(o, :mode => :compat)) }
37
- capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
38
- require 'json'
39
- require 'json/ext'
40
- JSON.generator = JSON::Ext::Generator
41
- JSON.parser = JSON::Ext::Parser
42
- JSON.load(JSON.generate(o))
43
- }
44
-
45
- module One
46
- module Two
47
- module Three
48
- class Empty
49
-
50
- def initialize()
51
- @a = 1
52
- @b = 2
53
- @c = 3
54
- end
55
-
56
- def eql?(o)
57
- self.class == o.class && @a == o.a && @b = o.b && @c = o.c
58
- end
59
- alias == eql?
60
-
61
- def as_json(*a)
62
- {JSON.create_id => self.class.name, 'a' => @a, 'b' => @b, 'c' => @c }
63
- end
64
-
65
- def to_json(*a)
66
- JSON.generate(as_json())
67
- end
68
-
69
- def self.json_create(h)
70
- self.new()
71
- end
72
- end # Empty
73
- end # Three
74
- end # Two
75
- end # One
76
-
77
- $obj = {
78
- 'a' => 'Alpha', # string
79
- 'b' => true, # boolean
80
- 'c' => 12345, # number
81
- 'd' => [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
82
- 'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
83
- 'f' => nil, # nil
84
- 'g' => One::Two::Three::Empty.new(),
85
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
86
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
87
- }
88
-
89
- Oj.default_options = { :indent => $indent, :mode => :compat, :use_to_json => true, :create_additions => true, :create_id => '^o' }
90
-
91
- if 0 < $size
92
- s = Oj.dump($obj).size + 1
93
- cnt = $size * 1024 / s
94
- o = $obj
95
- $obj = []
96
- cnt.times do
97
- $obj << o
98
- end
99
- end
100
-
101
- $json = Oj.dump($obj)
102
- $failed = {} # key is same as String used in tests later
103
-
104
- if $verbose
105
- puts "size: #{$json.size}"
106
- puts "json:\n#{$json}\n"
107
- puts "Oj:compat loaded object:\n#{Oj.compat_load($json)}\n"
108
- puts "JSON loaded object:\n#{JSON::Ext::Parser.new($json).parse}\n"
109
- end
110
-
111
- puts '-' * 80
112
- puts "Compat Parse Performance"
113
- perf = Perf.new()
114
- unless $failed.has_key?('JSON::Ext')
115
- perf.add('JSON::Ext', 'parse') { JSON.load($json) }
116
- perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
117
- end
118
- unless $failed.has_key?('Oj:compat')
119
- perf.add('Oj:compat', 'compat_load') { Oj.compat_load($json) }
120
- end
121
- perf.run($iter)
122
-
123
- puts
124
- puts '-' * 80
125
- puts
126
-
127
- unless $failed.empty?
128
- puts "The following packages were not included for the reason listed"
129
- $failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
130
- end
data/test/perf_dump.rb DELETED
@@ -1,50 +0,0 @@
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_fast.rb DELETED
@@ -1,164 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
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 'yajl'
10
- require 'perf'
11
- require 'json'
12
- require 'json/ext'
13
- require 'oj'
14
-
15
- $verbose = false
16
- $indent = 0
17
- $iter = 100000
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
- files = opts.parse(ARGV)
33
-
34
- # This just navigates to each leaf of the JSON structure.
35
- def dig(obj, &blk)
36
- case obj
37
- when Array
38
- obj.each { |e| dig(e, &blk) }
39
- when Hash
40
- obj.values.each { |e| dig(e, &blk) }
41
- else
42
- blk.yield(obj)
43
- end
44
- end
45
-
46
- $obj = {
47
- 'a' => 'Alpha', # string
48
- 'b' => true, # boolean
49
- 'c' => 12345, # number
50
- 'd' => [ true, [false, {'12345' => 12345, 'nil' => nil}, 3.967, { 'x' => 'something', 'y' => false, 'z' => true}, nil]], # mix it up array
51
- 'e' => { 'one' => 1, 'two' => 2 }, # hash
52
- 'f' => nil, # nil
53
- 'g' => 12345678901234567890123456789, # big number
54
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
55
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
56
- }
57
-
58
- Oj.default_options = { :indent => $indent, :mode => :compat }
59
-
60
- $json = Oj.dump($obj)
61
- $failed = {} # key is same as String used in tests later
62
-
63
- def capture_error(tag, orig, load_key, dump_key, &blk)
64
- begin
65
- obj = blk.call(orig)
66
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
67
- rescue Exception => e
68
- $failed[tag] = "#{e.class}: #{e.message}"
69
- end
70
- end
71
-
72
- # Verify that all packages dump and load correctly and return the same Object as the original.
73
- capture_error('Oj::Doc', $obj, 'load', 'dump') { |o| Oj::Doc.open(Oj.dump(o, :mode => :strict)) { |f| f.fetch() } }
74
- #capture_error('Yajl', $obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
75
- capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
76
-
77
- if $verbose
78
- puts "json:\n#{$json}\n"
79
- end
80
-
81
- puts '-' * 80
82
- puts "Parse Performance"
83
- perf = Perf.new()
84
- perf.add('Oj::Doc', 'parse') { Oj::Doc.open($json) {|f| } } unless $failed.has_key?('Oj::Doc')
85
- #perf.add('Yajl', 'parse') { Yajl::Parser.parse($json) } unless $failed.has_key?('Yajl')
86
- perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new($json).parse } unless $failed.has_key?('JSON::Ext')
87
- perf.run($iter)
88
-
89
- puts '-' * 80
90
- puts "JSON generation Performance"
91
- Oj::Doc.open($json) do |doc|
92
- perf = Perf.new()
93
- perf.add('Oj::Doc', 'dump') { doc.dump() }
94
- # perf.add('Yajl', 'encode') { Yajl::Encoder.encode($obj) }
95
- perf.add('JSON::Ext', 'fast_generate') { JSON.fast_generate($obj) }
96
- perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
97
- perf.run($iter)
98
- end
99
-
100
- if 0 < $gets
101
- puts '-' * 80
102
- puts "Parse and get all values Performance"
103
- perf = Perf.new()
104
- perf.add('Oj::Doc', 'parse') { Oj::Doc.open($json) {|f| $gets.times { f.each_value() {} } } } unless $failed.has_key?('Oj::Doc')
105
- # perf.add('Yajl', 'parse') { $gets.times { dig(Yajl::Parser.parse($json)) {} } } unless $failed.has_key?('Yajl')
106
- perf.add('JSON::Ext', 'parse') { $gets.times { dig(JSON::Ext::Parser.new($json).parse) {} } } unless $failed.has_key?('JSON::Ext')
107
- perf.run($iter)
108
- end
109
-
110
- if $fetch
111
- puts '-' * 80
112
- puts "fetch nested Performance"
113
- json_hash = Oj.load($json, :mode => :strict)
114
- Oj::Doc.open($json) do |fast|
115
- #puts "*** C fetch: #{fast.fetch('/d/2/4/y')}"
116
- #puts "*** Ruby fetch: #{json_hash.fetch('d', []).fetch(1, []).fetch(3, []).fetch('x', nil)}"
117
- perf = Perf.new()
118
- perf.add('Oj::Doc', 'fetch') { fast.fetch('/d/2/4/x'); fast.fetch('/h/a/b/c/d/e/f/g'); fast.fetch('/i/1/1/1/1/1/1/1') }
119
- # version that fails gracefully
120
- perf.add('Ruby', 'fetch') do
121
- json_hash.fetch('d', []).fetch(1, []).fetch(3, []).fetch('x', nil)
122
- json_hash.fetch('h', {}).fetch('a', {}).fetch('b', {}).fetch('c', {}).fetch('d', {}).fetch('e', {}).fetch('f', {}).fetch('g', {})
123
- json_hash.fetch('i', []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, nil)
124
- end
125
- # version that raises if the path is incorrect
126
- # perf.add('Ruby', 'fetch') { $fetch.times { json_hash['d'][1][3][1] } }
127
- perf.run($iter)
128
- end
129
- end
130
-
131
- if $write
132
- puts '-' * 80
133
- puts "JSON write to file Performance"
134
- Oj::Doc.open($json) do |doc|
135
- perf = Perf.new()
136
- perf.add('Oj::Doc', 'dump') { doc.dump(nil, 'oj.json') }
137
- # perf.add('Yajl', 'encode') { File.open('yajl.json', 'w') { |f| Yajl::Encoder.encode($obj, f) } }
138
- perf.add('JSON::Ext', 'fast_generate') { File.open('json_ext.json', 'w') { |f| f.write(JSON.fast_generate($obj)) } }
139
- perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
140
- perf.run($iter)
141
- end
142
- end
143
-
144
- if $read
145
- puts '-' * 80
146
- puts "JSON read from file Performance"
147
- Oj::Doc.open($json) { |doc| doc.dump(nil, 'oj.json') }
148
- # File.open('yajl.json', 'w') { |f| Yajl::Encoder.encode($obj, f) }
149
- JSON.generator = JSON::Ext::Generator
150
- File.open('json_ext.json', 'w') { |f| f.write(JSON.fast_generate($obj)) }
151
- Oj::Doc.open($json) do |doc|
152
- perf = Perf.new()
153
- perf.add('Oj::Doc', 'open_file') { ::Oj::Doc.open_file('oj.json') }
154
- # perf.add('Yajl', 'decode') { Yajl::decoder.decode(File.read('yajl.json')) }
155
- perf.add('JSON::Ext', '') { JSON.parse(File.read('json_ext.json')) }
156
- perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
157
- perf.run($iter)
158
- end
159
- end
160
-
161
- unless $failed.empty?
162
- puts "The following packages were not included for the reason listed"
163
- $failed.each { |tag,msg| puts "***** #{tag}: #{msg}" }
164
- end
data/test/perf_file.rb DELETED
@@ -1,64 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
-
3
- $: << '.'
4
- $: << '../lib'
5
- $: << '../ext'
6
-
7
- if __FILE__ == $0
8
- if (i = ARGV.index('-I'))
9
- x,path = ARGV.slice!(i, 2)
10
- $: << path
11
- end
12
- end
13
-
14
- require 'optparse'
15
- require 'oj'
16
- require 'perf'
17
-
18
- $indent = 0
19
- $iter = 1
20
- $size = 1
21
-
22
- opts = OptionParser.new
23
-
24
- opts.on("-r", "read") { do_read = true }
25
- opts.on("-c", "--count [Int]", Integer, "iterations") { |i| $iter = i }
26
- opts.on("-i", "--indent [Int]", Integer, "indent") { |i| $indent = i }
27
- opts.on("-s", "--size [Int]", Integer, "size in Mbytes") { |s| $size = s }
28
-
29
- opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
30
- files = opts.parse(ARGV)
31
-
32
- $obj = {
33
- 'a' => 'Alpha', # string
34
- 'b' => true, # boolean
35
- 'c' => 12345, # number
36
- 'd' => [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
37
- 'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
38
- 'f' => nil, # nil
39
- 'g' => 12345678901234567890123456789, #_bignum
40
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
41
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
42
- }
43
-
44
- json = Oj.dump($obj, :indent => $indent)
45
- cnt = ($size * 1024 * 1024 + json.size) / json.size
46
- cnt = 1 if 0 == $size
47
-
48
- filename = 'tmp.json'
49
- File.open(filename, "w") { |f|
50
- cnt.times do
51
- Oj.to_stream(f, $obj, :indent => $indent)
52
- end
53
- }
54
-
55
- Oj.default_options = { :mode => :strict, :indent => $indent }
56
-
57
- puts '-' * 80
58
- puts "Read from #{cnt * json.size / (1024 * 1024)} Mb file Performance"
59
- perf = Perf.new()
60
- perf.add('Oj.load_file', '') { Oj.load_file(filename) }
61
- perf.add('Oj.load(string)', '') { Oj.load(File.read(filename)) }
62
- perf.add('Oj.load(file)', '') { File.open(filename, 'r') { |f| Oj.load(f) } }
63
- perf.run($iter)
64
-
data/test/perf_object.rb DELETED
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $: << '.'
4
- $: << '../lib'
5
- $: << '../ext'
6
-
7
- if __FILE__ == $0
8
- if (i = ARGV.index('-I'))
9
- x,path = ARGV.slice!(i, 2)
10
- $: << path
11
- end
12
- end
13
-
14
- require 'optparse'
15
- require 'ox'
16
- require 'oj'
17
- require 'perf'
18
- require 'sample'
19
- require 'files'
20
-
21
- $circular = false
22
- $indent = 0
23
- $allow_gc = true
24
-
25
- do_sample = false
26
- do_files = false
27
-
28
- do_load = false
29
- do_dump = false
30
- do_read = false
31
- do_write = false
32
- $iter = 1000
33
- $mult = 1
34
-
35
- opts = OptionParser.new
36
- opts.on("-c", "circular options") { $circular = true }
37
-
38
- opts.on("-x", "use sample instead of files") { do_sample = true }
39
- opts.on("-g", "no GC during parsing") { $allow_gc = false }
40
-
41
- opts.on("-s", "load and dump as sample Ruby object") { do_sample = true }
42
- opts.on("-f", "load and dump as files Ruby object") { do_files = true }
43
-
44
- opts.on("-l", "load") { do_load = true }
45
- opts.on("-d", "dump") { do_dump = true }
46
- opts.on("-r", "read") { do_read = true }
47
- opts.on("-w", "write") { do_write = true }
48
- opts.on("-a", "load, dump, read and write") { do_load = true; do_dump = true; do_read = true; do_write = true }
49
-
50
- opts.on("-i", "--iterations [Int]", Integer, "iterations") { |i| $iter = i }
51
- opts.on("-m", "--multiply [Int]", Integer, "multiplier") { |i| $mult = i }
52
-
53
- opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
54
- files = opts.parse(ARGV)
55
-
56
- $obj = nil
57
- $xml = nil
58
- $mars = nil
59
- $json = nil
60
-
61
- unless do_load || do_dump || do_read || do_write
62
- do_load = true
63
- do_dump = true
64
- do_read = true
65
- do_write = true
66
- end
67
-
68
- # prepare all the formats for input
69
- if files.empty?
70
- $obj = []
71
- $mult.times do
72
- $obj << (do_sample ? sample_doc(2) : files('..'))
73
- end
74
-
75
- $mars = Marshal.dump($obj)
76
- $xml = Ox.dump($obj, :indent => $indent, :circular => $circular)
77
- $json = Oj.dump($obj, :indent => $indent, :circular => $circular, :mode => :object)
78
- File.open('sample.xml', 'w') { |f| f.write($xml) }
79
- File.open('sample.json', 'w') { |f| f.write($json) }
80
- File.open('sample.marshal', 'w') { |f| f.write($mars) }
81
- else
82
- puts "loading and parsing #{files}\n\n"
83
- data = files.map do |f|
84
- $xml = File.read(f)
85
- $obj = Ox.load($xml);
86
- $mars = Marshal.dump($obj)
87
- $json = Oj.dump($obj, :indent => $indent, :circular => $circular)
88
- end
89
- end
90
-
91
- Oj.default_options = { :mode => :object, :indent => $indent, :circular => $circular, :allow_gc => $allow_gc }
92
- #puts "json: #{$json.size}"
93
- #puts "xml: #{$xml.size}"
94
- #puts "marshal: #{$mars.size}"
95
-
96
-
97
- if do_load
98
- puts '-' * 80
99
- puts "Load Performance"
100
- perf = Perf.new()
101
- perf.add('Oj.object', 'load') { Oj.object_load($json) }
102
- perf.add('Ox', 'load') { Ox.load($xml, :mode => :object) }
103
- perf.add('Marshal', 'load') { Marshal.load($mars) }
104
- perf.run($iter)
105
- end
106
-
107
- if do_dump
108
- puts '-' * 80
109
- puts "Dump Performance"
110
- perf = Perf.new()
111
- perf.add('Oj', 'dump') { Oj.dump($obj) }
112
- perf.add('Ox', 'dump') { Ox.dump($obj, :indent => $indent, :circular => $circular) }
113
- perf.add('Marshal', 'dump') { Marshal.dump($obj) }
114
- perf.run($iter)
115
- end
116
-
117
- if do_read
118
- puts '-' * 80
119
- puts "Read from file Performance"
120
- perf = Perf.new()
121
- perf.add('Oj', 'load') { Oj.load_file('sample.json') }
122
- #perf.add('Oj', 'load') { Oj.load(File.read('sample.json')) }
123
- perf.add('Ox', 'load_file') { Ox.load_file('sample.xml', :mode => :object) }
124
- perf.add('Marshal', 'load') { Marshal.load(File.new('sample.marshal')) }
125
- perf.run($iter)
126
- end
127
-
128
- if do_write
129
- puts '-' * 80
130
- puts "Write to file Performance"
131
- perf = Perf.new()
132
- perf.add('Oj', 'to_file') { Oj.to_file('sample.json', $obj) }
133
- perf.add('Ox', 'to_file') { Ox.to_file('sample.xml', $obj, :indent => $indent, :circular => $circular) }
134
- perf.add('Marshal', 'dump') { Marshal.dump($obj, File.new('sample.marshal', 'w')) }
135
- perf.run($iter)
136
- end
137
-
138
-
data/test/perf_once.rb DELETED
@@ -1,58 +0,0 @@
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