oj 3.16.9 → 3.16.11

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/ext/oj/custom.c +10 -9
  4. data/ext/oj/dump.c +319 -20
  5. data/ext/oj/dump.h +7 -2
  6. data/ext/oj/dump_compat.c +9 -8
  7. data/ext/oj/dump_leaf.c +1 -1
  8. data/ext/oj/dump_object.c +27 -17
  9. data/ext/oj/dump_strict.c +7 -6
  10. data/ext/oj/fast.c +4 -7
  11. data/ext/oj/mimic_json.c +3 -6
  12. data/ext/oj/object.c +8 -8
  13. data/ext/oj/oj.c +12 -9
  14. data/ext/oj/parse.c +15 -5
  15. data/ext/oj/parser.c +1 -1
  16. data/ext/oj/parser.h +2 -0
  17. data/ext/oj/rails.c +20 -19
  18. data/ext/oj/saj.c +3 -6
  19. data/ext/oj/scp.c +3 -6
  20. data/ext/oj/simd.h +10 -0
  21. data/ext/oj/stream_writer.c +1 -7
  22. data/ext/oj/strict.c +2 -4
  23. data/ext/oj/string_writer.c +1 -3
  24. data/ext/oj/wab.c +4 -3
  25. data/lib/oj/version.rb +1 -1
  26. data/pages/Encoding.md +1 -1
  27. metadata +4 -98
  28. data/test/_test_active.rb +0 -75
  29. data/test/_test_active_mimic.rb +0 -95
  30. data/test/_test_mimic_rails.rb +0 -123
  31. data/test/activerecord/result_test.rb +0 -31
  32. data/test/activesupport6/abstract_unit.rb +0 -44
  33. data/test/activesupport6/decoding_test.rb +0 -133
  34. data/test/activesupport6/encoding_test.rb +0 -542
  35. data/test/activesupport6/encoding_test_cases.rb +0 -98
  36. data/test/activesupport6/test_common.rb +0 -17
  37. data/test/activesupport6/test_helper.rb +0 -163
  38. data/test/activesupport6/time_zone_test_helpers.rb +0 -39
  39. data/test/activesupport7/abstract_unit.rb +0 -52
  40. data/test/activesupport7/decoding_test.rb +0 -125
  41. data/test/activesupport7/encoding_test.rb +0 -536
  42. data/test/activesupport7/encoding_test_cases.rb +0 -104
  43. data/test/activesupport7/time_zone_test_helpers.rb +0 -47
  44. data/test/files.rb +0 -29
  45. data/test/foo.rb +0 -26
  46. data/test/helper.rb +0 -39
  47. data/test/isolated/shared.rb +0 -309
  48. data/test/isolated/test_mimic_after.rb +0 -13
  49. data/test/isolated/test_mimic_alone.rb +0 -12
  50. data/test/isolated/test_mimic_as_json.rb +0 -45
  51. data/test/isolated/test_mimic_before.rb +0 -13
  52. data/test/isolated/test_mimic_define.rb +0 -28
  53. data/test/isolated/test_mimic_rails_after.rb +0 -22
  54. data/test/isolated/test_mimic_rails_before.rb +0 -21
  55. data/test/isolated/test_mimic_redefine.rb +0 -15
  56. data/test/json_gem/json_addition_test.rb +0 -216
  57. data/test/json_gem/json_common_interface_test.rb +0 -155
  58. data/test/json_gem/json_encoding_test.rb +0 -107
  59. data/test/json_gem/json_ext_parser_test.rb +0 -21
  60. data/test/json_gem/json_fixtures_test.rb +0 -36
  61. data/test/json_gem/json_generator_test.rb +0 -413
  62. data/test/json_gem/json_generic_object_test.rb +0 -90
  63. data/test/json_gem/json_parser_test.rb +0 -477
  64. data/test/json_gem/json_string_matching_test.rb +0 -42
  65. data/test/json_gem/test_helper.rb +0 -30
  66. data/test/mem.rb +0 -34
  67. data/test/perf.rb +0 -102
  68. data/test/perf_compat.rb +0 -128
  69. data/test/perf_dump.rb +0 -50
  70. data/test/perf_fast.rb +0 -162
  71. data/test/perf_file.rb +0 -62
  72. data/test/perf_object.rb +0 -134
  73. data/test/perf_once.rb +0 -59
  74. data/test/perf_parser.rb +0 -183
  75. data/test/perf_saj.rb +0 -101
  76. data/test/perf_scp.rb +0 -140
  77. data/test/perf_simple.rb +0 -289
  78. data/test/perf_strict.rb +0 -137
  79. data/test/perf_wab.rb +0 -129
  80. data/test/prec.rb +0 -23
  81. data/test/sample/change.rb +0 -13
  82. data/test/sample/dir.rb +0 -18
  83. data/test/sample/doc.rb +0 -35
  84. data/test/sample/file.rb +0 -47
  85. data/test/sample/group.rb +0 -15
  86. data/test/sample/hasprops.rb +0 -15
  87. data/test/sample/layer.rb +0 -11
  88. data/test/sample/line.rb +0 -20
  89. data/test/sample/oval.rb +0 -10
  90. data/test/sample/rect.rb +0 -9
  91. data/test/sample/shape.rb +0 -34
  92. data/test/sample/text.rb +0 -19
  93. data/test/sample.rb +0 -54
  94. data/test/sample_json.rb +0 -37
  95. data/test/test_compat.rb +0 -567
  96. data/test/test_custom.rb +0 -555
  97. data/test/test_debian.rb +0 -50
  98. data/test/test_fast.rb +0 -526
  99. data/test/test_file.rb +0 -250
  100. data/test/test_gc.rb +0 -60
  101. data/test/test_generate.rb +0 -21
  102. data/test/test_hash.rb +0 -39
  103. data/test/test_integer_range.rb +0 -72
  104. data/test/test_null.rb +0 -376
  105. data/test/test_object.rb +0 -1030
  106. data/test/test_parser.rb +0 -11
  107. data/test/test_parser_debug.rb +0 -27
  108. data/test/test_parser_saj.rb +0 -337
  109. data/test/test_parser_usual.rb +0 -255
  110. data/test/test_rails.rb +0 -35
  111. data/test/test_saj.rb +0 -188
  112. data/test/test_scp.rb +0 -431
  113. data/test/test_strict.rb +0 -441
  114. data/test/test_various.rb +0 -801
  115. data/test/test_wab.rb +0 -311
  116. data/test/test_writer.rb +0 -396
  117. data/test/tests.rb +0 -33
  118. data/test/tests_mimic.rb +0 -23
  119. data/test/tests_mimic_addition.rb +0 -16
data/test/perf_compat.rb DELETED
@@ -1,128 +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
-
12
- $verbose = false
13
- $indent = 0
14
- $iter = 20_000
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
- opts.parse(ARGV)
24
-
25
- def capture_error(tag, orig, load_key, dump_key, &blk)
26
- obj = blk.call(orig)
27
- puts obj unless orig == obj
28
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
29
- rescue Exception => e
30
- $failed[tag] = "#{e.class}: #{e.message}"
31
- end
32
-
33
- # Verify that all packages dump and load correctly and return the same Object as the original.
34
- capture_error('Oj:compat', $obj, 'load', 'dump') { |o| Oj.compat_load(Oj.dump(o, :mode => :compat)) }
35
- capture_error('JSON::Ext', $obj, 'generate', 'parse') { |o|
36
- require 'json'
37
- require 'json/ext'
38
- JSON.generator = JSON::Ext::Generator
39
- JSON.parser = JSON::Ext::Parser
40
- JSON.parse(JSON.generate(o))
41
- }
42
-
43
- module One
44
- module Two
45
- module Three
46
- class Empty
47
-
48
- def initialize
49
- @a = 1
50
- @b = 2
51
- @c = 3
52
- end
53
-
54
- def eql?(o)
55
- self.class == o.class && @a == o.a && @b = o.b && @c = o.c
56
- end
57
- alias == eql?
58
-
59
- def as_json(*_a)
60
- {JSON.create_id => self.class.name, 'a' => @a, 'b' => @b, 'c' => @c }
61
- end
62
-
63
- def to_json(*_a)
64
- JSON.generate(as_json())
65
- end
66
-
67
- def self.json_create(_h)
68
- new()
69
- end
70
- end # Empty
71
- end # Three
72
- end # Two
73
- end # One
74
-
75
- $obj = {
76
- 'a' => 'Alpha', # string
77
- 'b' => true, # boolean
78
- 'c' => 12_345, # number
79
- 'd' => [ true, [false, [-123_456_789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
80
- 'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
81
- 'f' => nil, # nil
82
- 'g' => One::Two::Three::Empty.new(),
83
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
84
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
85
- }
86
-
87
- Oj.default_options = { :indent => $indent, :mode => :compat, :use_to_json => true, :create_additions => true, :create_id => '^o' }
88
-
89
- if 0 < $size
90
- s = Oj.dump($obj).size + 1
91
- cnt = $size * 1024 / s
92
- o = $obj
93
- $obj = []
94
- cnt.times do
95
- $obj << o
96
- end
97
- end
98
-
99
- $json = Oj.dump($obj)
100
- $failed = {} # key is same as String used in tests later
101
-
102
- if $verbose
103
- puts "size: #{$json.size}"
104
- puts "json:\n#{$json}\n"
105
- puts "Oj:compat loaded object:\n#{Oj.compat_load($json)}\n"
106
- puts "JSON loaded object:\n#{JSON::Ext::Parser.new($json).parse}\n"
107
- end
108
-
109
- puts '-' * 80
110
- puts 'Compat Parse Performance'
111
- perf = Perf.new()
112
- unless $failed.key?('JSON::Ext')
113
- perf.add('JSON::Ext', 'parse') { JSON.parse($json) }
114
- perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
115
- end
116
- unless $failed.key?('Oj:compat')
117
- perf.add('Oj:compat', 'compat_load') { Oj.compat_load($json) }
118
- end
119
- perf.run($iter)
120
-
121
- puts
122
- puts '-' * 80
123
- puts
124
-
125
- unless $failed.empty?
126
- puts 'The following packages were not included for the reason listed'
127
- $failed.each { |tag, msg| puts "***** #{tag}: #{msg}" }
128
- end
data/test/perf_dump.rb DELETED
@@ -1,50 +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 '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
- opts.parse(ARGV)
23
-
24
- @obj = {
25
- 'a' => 'Alpha', # string
26
- 'b' => true, # boolean
27
- 'c' => 12_345, # number
28
- 'd' => [ true, [false, [-123_456_789, 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,162 +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 = 100_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
- # 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.each_value { |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' => 12_345, # number
50
- 'd' => [ true, [false, {'12345' => 12_345, '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' => 12_345_678_901_234_567_890_123_456_789, # 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
- obj = blk.call(orig)
65
- raise "#{tag} #{dump_key} and #{load_key} did not return the same object as the original." unless orig == obj
66
- rescue Exception => e
67
- @failed[tag] = "#{e.class}: #{e.message}"
68
- end
69
-
70
- # Verify that all packages dump and load correctly and return the same Object as the original.
71
- capture_error('Oj::Doc', @obj, 'load', 'dump') { |o| Oj::Doc.open(Oj.dump(o, :mode => :strict)) { |f| f.fetch() } }
72
- # capture_error('Yajl', @obj, 'encode', 'parse') { |o| Yajl::Parser.parse(Yajl::Encoder.encode(o)) }
73
- capture_error('JSON::Ext', @obj, 'generate', 'parse') { |o| JSON.generator = JSON::Ext::Generator; JSON::Ext::Parser.new(JSON.generate(o)).parse }
74
-
75
- if @verbose
76
- puts "json:\n#{@json}\n"
77
- end
78
-
79
- puts '-' * 80
80
- puts 'Parse Performance'
81
- perf = Perf.new()
82
- perf.add('Oj::Doc', 'parse') { Oj::Doc.open(@json) { |f| } } unless @failed.key?('Oj::Doc')
83
- # perf.add('Yajl', 'parse') { Yajl::Parser.parse(@json) } unless @failed.has_key?('Yajl')
84
- perf.add('JSON::Ext', 'parse') { JSON::Ext::Parser.new(@json).parse } unless @failed.key?('JSON::Ext')
85
- perf.run(@iter)
86
-
87
- puts '-' * 80
88
- puts 'JSON generation Performance'
89
- Oj::Doc.open(@json) do |doc|
90
- perf = Perf.new()
91
- perf.add('Oj::Doc', 'dump') { doc.dump() }
92
- # perf.add('Yajl', 'encode') { Yajl::Encoder.encode(@obj) }
93
- perf.add('JSON::Ext', 'fast_generate') { JSON.fast_generate(@obj) }
94
- perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
95
- perf.run(@iter)
96
- end
97
-
98
- if 0 < @gets
99
- puts '-' * 80
100
- puts 'Parse and get all values Performance'
101
- perf = Perf.new()
102
- perf.add('Oj::Doc', 'parse') { Oj::Doc.open(@json) { |f| @gets.times { f.each_value() {} } } } unless @failed.key?('Oj::Doc')
103
- # perf.add('Yajl', 'parse') { @gets.times { dig(Yajl::Parser.parse(@json)) {} } } unless @failed.has_key?('Yajl')
104
- perf.add('JSON::Ext', 'parse') { @gets.times { dig(JSON::Ext::Parser.new(@json).parse) {} } } unless @failed.key?('JSON::Ext')
105
- perf.run(@iter)
106
- end
107
-
108
- if @fetch
109
- puts '-' * 80
110
- puts 'fetch nested Performance'
111
- json_hash = Oj.load(@json, :mode => :strict)
112
- Oj::Doc.open(@json) do |fast|
113
- # puts "*** C fetch: #{fast.fetch('/d/2/4/y')}"
114
- # puts "*** Ruby fetch: #{json_hash.fetch('d', []).fetch(1, []).fetch(3, []).fetch('x', nil)}"
115
- perf = Perf.new()
116
- 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') }
117
- # version that fails gracefully
118
- perf.add('Ruby', 'fetch') do
119
- json_hash.fetch('d', []).fetch(1, []).fetch(3, []).fetch('x', nil)
120
- json_hash.fetch('h', {}).fetch('a', {}).fetch('b', {}).fetch('c', {}).fetch('d', {}).fetch('e', {}).fetch('f', {}).fetch('g', {})
121
- json_hash.fetch('i', []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, []).fetch(0, nil)
122
- end
123
- # version that raises if the path is incorrect
124
- # perf.add('Ruby', 'fetch') { @fetch.times { json_hash['d'][1][3][1] } }
125
- perf.run(@iter)
126
- end
127
- end
128
-
129
- if @write
130
- puts '-' * 80
131
- puts 'JSON write to file Performance'
132
- Oj::Doc.open(@json) do |doc|
133
- perf = Perf.new()
134
- perf.add('Oj::Doc', 'dump') { doc.dump(nil, 'oj.json') }
135
- # perf.add('Yajl', 'encode') { File.open('yajl.json', 'w') { |f| Yajl::Encoder.encode(@obj, f) } }
136
- perf.add('JSON::Ext', 'fast_generate') { File.write('json_ext.json', JSON.fast_generate(@obj)) }
137
- perf.before('JSON::Ext') { JSON.generator = JSON::Ext::Generator }
138
- perf.run(@iter)
139
- end
140
- end
141
-
142
- if @read
143
- puts '-' * 80
144
- puts 'JSON read from file Performance'
145
- Oj::Doc.open(@json) { |doc| doc.dump(nil, 'oj.json') }
146
- # File.open('yajl.json', 'w') { |f| Yajl::Encoder.encode(@obj, f) }
147
- JSON.generator = JSON::Ext::Generator
148
- File.write('json_ext.json', JSON.fast_generate(@obj))
149
- Oj::Doc.open(@json) do |_doc|
150
- perf = Perf.new()
151
- perf.add('Oj::Doc', 'open_file') { Oj::Doc.open_file('oj.json') }
152
- # perf.add('Yajl', 'decode') { Yajl::decoder.decode(File.read('yajl.json')) }
153
- perf.add('JSON::Ext', '') { JSON.parse(File.read('json_ext.json')) }
154
- perf.before('JSON::Ext') { JSON.parser = JSON::Ext::Parser }
155
- perf.run(@iter)
156
- end
157
- end
158
-
159
- unless @failed.empty?
160
- puts 'The following packages were not included for the reason listed'
161
- @failed.each { |tag, msg| puts "***** #{tag}: #{msg}" }
162
- end
data/test/perf_file.rb DELETED
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env ruby -wW1
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << '.'
5
- $LOAD_PATH << '../lib'
6
- $LOAD_PATH << '../ext'
7
-
8
- if __FILE__ == $PROGRAM_NAME && (i = ARGV.index('-I'))
9
- _, path = ARGV.slice!(i, 2)
10
- $LOAD_PATH << path
11
- end
12
-
13
- require 'optparse'
14
- require 'oj'
15
- require 'perf'
16
-
17
- @indent = 0
18
- @iter = 1
19
- @size = 1
20
-
21
- opts = OptionParser.new
22
-
23
- opts.on('-r', 'read') { true }
24
- opts.on('-c', '--count [Int]', Integer, 'iterations') { |v| @iter = v }
25
- opts.on('-i', '--indent [Int]', Integer, 'indent') { |v| @indent = v }
26
- opts.on('-s', '--size [Int]', Integer, 'size in Mbytes') { |s| @size = s }
27
-
28
- opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) }
29
- opts.parse(ARGV)
30
-
31
- @obj = {
32
- 'a' => 'Alpha', # string
33
- 'b' => true, # boolean
34
- 'c' => 12_345, # number
35
- 'd' => [ true, [false, [-123_456_789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
36
- 'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
37
- 'f' => nil, # nil
38
- 'g' => 12_345_678_901_234_567_890_123_456_789, # _bignum
39
- 'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
40
- 'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
41
- }
42
-
43
- json = Oj.dump(@obj, :indent => @indent)
44
- cnt = ((@size * 1024 * 1024) + json.size) / json.size
45
- cnt = 1 if 0 == @size
46
-
47
- filename = 'tmp.json'
48
- File.open(filename, 'w') { |f|
49
- cnt.times do
50
- Oj.to_stream(f, @obj, :indent => @indent)
51
- end
52
- }
53
-
54
- Oj.default_options = { :mode => :strict, :indent => @indent }
55
-
56
- puts '-' * 80
57
- puts "Read from #{cnt * json.size / (1024 * 1024)} Mb file Performance"
58
- perf = Perf.new()
59
- perf.add('Oj.load_file', '') { Oj.load_file(filename) }
60
- perf.add('Oj.load(string)', '') { Oj.load(File.read(filename)) }
61
- perf.add('Oj.load(file)', '') { File.open(filename, 'r') { |f| Oj.load(f) } }
62
- perf.run(@iter)
data/test/perf_object.rb DELETED
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- $LOAD_PATH << '.'
5
- $LOAD_PATH << '../lib'
6
- $LOAD_PATH << '../ext'
7
-
8
- if __FILE__ == $PROGRAM_NAME && (i = ARGV.index('-I'))
9
- _, path = ARGV.slice!(i, 2)
10
- $LOAD_PATH << path
11
- end
12
-
13
- require 'optparse'
14
- require 'ox'
15
- require 'oj'
16
- require 'perf'
17
- require 'sample'
18
- require 'files'
19
-
20
- @circular = false
21
- @indent = 0
22
- @allow_gc = true
23
-
24
- do_sample = false
25
- do_files = false
26
-
27
- do_load = false
28
- do_dump = false
29
- do_read = false
30
- do_write = false
31
- @iter = 1000
32
- @mult = 1
33
-
34
- opts = OptionParser.new
35
- opts.on('-c', 'circular options') { @circular = true }
36
-
37
- opts.on('-x', 'use sample instead of files') { do_sample = true }
38
- opts.on('-g', 'no GC during parsing') { @allow_gc = false }
39
-
40
- opts.on('-s', 'load and dump as sample Ruby object') { do_sample = true }
41
- opts.on('-f', 'load and dump as files Ruby object') { do_files = true }
42
-
43
- opts.on('-l', 'load') { do_load = true }
44
- opts.on('-d', 'dump') { do_dump = true }
45
- opts.on('-r', 'read') { do_read = true }
46
- opts.on('-w', 'write') { do_write = true }
47
- opts.on('-a', 'load, dump, read and write') { do_load = true; do_dump = true; do_read = true; do_write = true }
48
-
49
- opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |v| @iter = v }
50
- opts.on('-m', '--multiply [Int]', Integer, 'multiplier') { |v| @mult = v }
51
-
52
- opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) }
53
- files = opts.parse(ARGV)
54
-
55
- @obj = nil
56
- @xml = nil
57
- @mars = nil
58
- @json = nil
59
-
60
- unless do_load || do_dump || do_read || do_write
61
- do_load = true
62
- do_dump = true
63
- do_read = true
64
- do_write = true
65
- end
66
-
67
- # prepare all the formats for input
68
- if files.empty?
69
- @obj = []
70
- @mult.times do
71
- @obj << (do_sample ? sample_doc(2) : files('..'))
72
- end
73
-
74
- @mars = Marshal.dump(@obj)
75
- @xml = Ox.dump(@obj, :indent => @indent, :circular => @circular)
76
- @json = Oj.dump(@obj, :indent => @indent, :circular => @circular, :mode => :object)
77
- File.write('sample.xml', @xml)
78
- File.write('sample.json', @json)
79
- File.write('sample.marshal', @mars)
80
- else
81
- puts "loading and parsing #{files}\n\n"
82
- files.map do |f|
83
- @xml = File.read(f)
84
- @obj = Ox.load(@xml)
85
- @mars = Marshal.dump(@obj)
86
- @json = Oj.dump(@obj, :indent => @indent, :circular => @circular)
87
- end
88
- end
89
-
90
- Oj.default_options = { :mode => :object, :indent => @indent, :circular => @circular, :allow_gc => @allow_gc }
91
- # puts "json: #{@json.size}"
92
- # puts "xml: #{@xml.size}"
93
- # puts "marshal: #{@mars.size}"
94
-
95
- if do_load
96
- puts '-' * 80
97
- puts 'Load Performance'
98
- perf = Perf.new()
99
- perf.add('Oj.object', 'load') { Oj.object_load(@json) }
100
- perf.add('Ox', 'load') { Ox.load(@xml, :mode => :object) }
101
- perf.add('Marshal', 'load') { Marshal.load(@mars) }
102
- perf.run(@iter)
103
- end
104
-
105
- if do_dump
106
- puts '-' * 80
107
- puts 'Dump Performance'
108
- perf = Perf.new()
109
- perf.add('Oj', 'dump') { Oj.dump(@obj) }
110
- perf.add('Ox', 'dump') { Ox.dump(@obj, :indent => @indent, :circular => @circular) }
111
- perf.add('Marshal', 'dump') { Marshal.dump(@obj) }
112
- perf.run(@iter)
113
- end
114
-
115
- if do_read
116
- puts '-' * 80
117
- puts 'Read from file Performance'
118
- perf = Perf.new()
119
- perf.add('Oj', 'load') { Oj.load_file('sample.json') }
120
- # perf.add('Oj', 'load') { Oj.load(File.read('sample.json')) }
121
- perf.add('Ox', 'load_file') { Ox.load_file('sample.xml', :mode => :object) }
122
- perf.add('Marshal', 'load') { Marshal.load(File.new('sample.marshal')) }
123
- perf.run(@iter)
124
- end
125
-
126
- if do_write
127
- puts '-' * 80
128
- puts 'Write to file Performance'
129
- perf = Perf.new()
130
- perf.add('Oj', 'to_file') { Oj.to_file('sample.json', @obj) }
131
- perf.add('Ox', 'to_file') { Ox.to_file('sample.xml', @obj, :indent => @indent, :circular => @circular) }
132
- perf.add('Marshal', 'dump') { Marshal.dump(@obj, File.new('sample.marshal', 'w')) }
133
- perf.run(@iter)
134
- end
data/test/perf_once.rb DELETED
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'English'
5
- $LOAD_PATH << '.'
6
- $LOAD_PATH << File.join(__dir__, '../lib')
7
- $LOAD_PATH << File.join(__dir__, '../ext')
8
-
9
- require 'oj'
10
-
11
- filename = 'tmp.json'
12
- File.open(filename, 'w') { |f|
13
- cnt = 0
14
- f.puts('{')
15
- ('a'..'z').each { |a|
16
- ('a'..'z').each { |b|
17
- ('a'..'z').each { |c|
18
- ('a'..'z').each { |d|
19
- f.puts(%|"#{a}#{b}#{c}#{d}":#{cnt},|)
20
- cnt += 1
21
- }
22
- }
23
- }
24
- }
25
- f.puts('"_last":0}')
26
- }
27
-
28
- def mem
29
- `ps -o rss= -p #{$PROCESS_ID}`.to_i
30
- end
31
-
32
- Oj.default_options = { mode: :strict, cache_keys: false, cache_str: -1 }
33
- start = Time.now
34
- Oj.load_file('tmp.json')
35
- dur = Time.now - start
36
- GC.start
37
- puts "no cache duration: #{dur} @ #{mem}"
38
-
39
- Oj.default_options = { cache_keys: true }
40
- start = Time.now
41
- Oj.load_file('tmp.json')
42
- dur = Time.now - start
43
- GC.start
44
- puts "initial cache duration: #{dur} @ #{mem}"
45
-
46
- start = Time.now
47
- Oj.load_file('tmp.json')
48
- dur = Time.now - start
49
- GC.start
50
- puts "second cache duration: #{dur} @ #{mem}"
51
-
52
- 10.times { GC.start }
53
- start = Time.now
54
- Oj.load_file('tmp.json')
55
- dur = Time.now - start
56
- GC.start
57
- puts "after several GCs cache duration: #{dur} @ #{mem}"
58
-
59
- # TBD check memory use