oj 3.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +104 -0
  4. data/ext/oj/buf.h +103 -0
  5. data/ext/oj/cache8.c +107 -0
  6. data/ext/oj/cache8.h +48 -0
  7. data/ext/oj/circarray.c +68 -0
  8. data/ext/oj/circarray.h +23 -0
  9. data/ext/oj/code.c +235 -0
  10. data/ext/oj/code.h +42 -0
  11. data/ext/oj/compat.c +299 -0
  12. data/ext/oj/custom.c +1191 -0
  13. data/ext/oj/dump.c +1252 -0
  14. data/ext/oj/dump.h +96 -0
  15. data/ext/oj/dump_compat.c +977 -0
  16. data/ext/oj/dump_leaf.c +252 -0
  17. data/ext/oj/dump_object.c +837 -0
  18. data/ext/oj/dump_strict.c +433 -0
  19. data/ext/oj/encode.h +45 -0
  20. data/ext/oj/err.c +57 -0
  21. data/ext/oj/err.h +70 -0
  22. data/ext/oj/extconf.rb +47 -0
  23. data/ext/oj/fast.c +1771 -0
  24. data/ext/oj/hash.c +163 -0
  25. data/ext/oj/hash.h +46 -0
  26. data/ext/oj/hash_test.c +512 -0
  27. data/ext/oj/mimic_json.c +878 -0
  28. data/ext/oj/object.c +771 -0
  29. data/ext/oj/odd.c +231 -0
  30. data/ext/oj/odd.h +44 -0
  31. data/ext/oj/oj.c +1704 -0
  32. data/ext/oj/oj.h +385 -0
  33. data/ext/oj/parse.c +1086 -0
  34. data/ext/oj/parse.h +111 -0
  35. data/ext/oj/rails.c +1493 -0
  36. data/ext/oj/rails.h +21 -0
  37. data/ext/oj/reader.c +231 -0
  38. data/ext/oj/reader.h +151 -0
  39. data/ext/oj/resolve.c +102 -0
  40. data/ext/oj/resolve.h +14 -0
  41. data/ext/oj/rxclass.c +147 -0
  42. data/ext/oj/rxclass.h +27 -0
  43. data/ext/oj/saj.c +714 -0
  44. data/ext/oj/scp.c +224 -0
  45. data/ext/oj/sparse.c +910 -0
  46. data/ext/oj/stream_writer.c +363 -0
  47. data/ext/oj/strict.c +212 -0
  48. data/ext/oj/string_writer.c +534 -0
  49. data/ext/oj/trace.c +79 -0
  50. data/ext/oj/trace.h +28 -0
  51. data/ext/oj/util.c +136 -0
  52. data/ext/oj/util.h +19 -0
  53. data/ext/oj/val_stack.c +118 -0
  54. data/ext/oj/val_stack.h +185 -0
  55. data/ext/oj/wab.c +631 -0
  56. data/lib/oj.rb +21 -0
  57. data/lib/oj/active_support_helper.rb +41 -0
  58. data/lib/oj/bag.rb +88 -0
  59. data/lib/oj/easy_hash.rb +52 -0
  60. data/lib/oj/error.rb +22 -0
  61. data/lib/oj/json.rb +176 -0
  62. data/lib/oj/mimic.rb +267 -0
  63. data/lib/oj/saj.rb +66 -0
  64. data/lib/oj/schandler.rb +142 -0
  65. data/lib/oj/state.rb +131 -0
  66. data/lib/oj/version.rb +5 -0
  67. data/pages/Advanced.md +22 -0
  68. data/pages/Compatibility.md +25 -0
  69. data/pages/Custom.md +23 -0
  70. data/pages/Encoding.md +65 -0
  71. data/pages/JsonGem.md +79 -0
  72. data/pages/Modes.md +155 -0
  73. data/pages/Options.md +283 -0
  74. data/pages/Rails.md +116 -0
  75. data/pages/Security.md +20 -0
  76. data/pages/WAB.md +13 -0
  77. data/test/_test_active.rb +76 -0
  78. data/test/_test_active_mimic.rb +96 -0
  79. data/test/_test_mimic_rails.rb +126 -0
  80. data/test/activerecord/result_test.rb +27 -0
  81. data/test/activesupport4/decoding_test.rb +108 -0
  82. data/test/activesupport4/encoding_test.rb +531 -0
  83. data/test/activesupport4/test_helper.rb +41 -0
  84. data/test/activesupport5/decoding_test.rb +125 -0
  85. data/test/activesupport5/encoding_test.rb +485 -0
  86. data/test/activesupport5/encoding_test_cases.rb +90 -0
  87. data/test/activesupport5/test_helper.rb +50 -0
  88. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  89. data/test/bar.rb +25 -0
  90. data/test/files.rb +29 -0
  91. data/test/foo.rb +167 -0
  92. data/test/helper.rb +26 -0
  93. data/test/isolated/shared.rb +308 -0
  94. data/test/isolated/test_mimic_after.rb +13 -0
  95. data/test/isolated/test_mimic_alone.rb +12 -0
  96. data/test/isolated/test_mimic_as_json.rb +45 -0
  97. data/test/isolated/test_mimic_before.rb +13 -0
  98. data/test/isolated/test_mimic_define.rb +28 -0
  99. data/test/isolated/test_mimic_rails_after.rb +22 -0
  100. data/test/isolated/test_mimic_rails_before.rb +21 -0
  101. data/test/isolated/test_mimic_redefine.rb +15 -0
  102. data/test/json_gem/json_addition_test.rb +216 -0
  103. data/test/json_gem/json_common_interface_test.rb +148 -0
  104. data/test/json_gem/json_encoding_test.rb +107 -0
  105. data/test/json_gem/json_ext_parser_test.rb +20 -0
  106. data/test/json_gem/json_fixtures_test.rb +35 -0
  107. data/test/json_gem/json_generator_test.rb +383 -0
  108. data/test/json_gem/json_generic_object_test.rb +90 -0
  109. data/test/json_gem/json_parser_test.rb +470 -0
  110. data/test/json_gem/json_string_matching_test.rb +42 -0
  111. data/test/json_gem/test_helper.rb +18 -0
  112. data/test/perf.rb +107 -0
  113. data/test/perf_compat.rb +130 -0
  114. data/test/perf_fast.rb +164 -0
  115. data/test/perf_file.rb +64 -0
  116. data/test/perf_object.rb +138 -0
  117. data/test/perf_saj.rb +109 -0
  118. data/test/perf_scp.rb +151 -0
  119. data/test/perf_simple.rb +287 -0
  120. data/test/perf_strict.rb +145 -0
  121. data/test/perf_wab.rb +131 -0
  122. data/test/sample.rb +54 -0
  123. data/test/sample/change.rb +14 -0
  124. data/test/sample/dir.rb +19 -0
  125. data/test/sample/doc.rb +36 -0
  126. data/test/sample/file.rb +48 -0
  127. data/test/sample/group.rb +16 -0
  128. data/test/sample/hasprops.rb +16 -0
  129. data/test/sample/layer.rb +12 -0
  130. data/test/sample/line.rb +20 -0
  131. data/test/sample/oval.rb +10 -0
  132. data/test/sample/rect.rb +10 -0
  133. data/test/sample/shape.rb +35 -0
  134. data/test/sample/text.rb +20 -0
  135. data/test/sample_json.rb +37 -0
  136. data/test/test_compat.rb +509 -0
  137. data/test/test_custom.rb +503 -0
  138. data/test/test_debian.rb +53 -0
  139. data/test/test_fast.rb +470 -0
  140. data/test/test_file.rb +239 -0
  141. data/test/test_gc.rb +49 -0
  142. data/test/test_hash.rb +29 -0
  143. data/test/test_integer_range.rb +73 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +1018 -0
  146. data/test/test_saj.rb +186 -0
  147. data/test/test_scp.rb +433 -0
  148. data/test/test_strict.rb +410 -0
  149. data/test/test_various.rb +741 -0
  150. data/test/test_wab.rb +307 -0
  151. data/test/test_writer.rb +380 -0
  152. data/test/tests.rb +24 -0
  153. data/test/tests_mimic.rb +14 -0
  154. data/test/tests_mimic_addition.rb +7 -0
  155. data/test/zoo.rb +13 -0
  156. metadata +359 -0
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ #frozen_string_literal: false
4
+
5
+ require 'json_gem/test_helper'
6
+
7
+ require 'time'
8
+
9
+ class JSONStringMatchingTest < Test::Unit::TestCase
10
+ include Test::Unit::TestCaseOmissionSupport
11
+
12
+ class TestTime < ::Time
13
+ def self.json_create(string)
14
+ Time.parse(string)
15
+ end
16
+
17
+ def to_json(*)
18
+ %{"#{strftime('%FT%T%z')}"}
19
+ end
20
+
21
+ def ==(other)
22
+ to_i == other.to_i
23
+ end
24
+ end
25
+
26
+ def test_match_date
27
+ t = TestTime.new
28
+ t_json = [ t ].to_json
29
+ time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/
30
+ assert_equal [ t ],
31
+ JSON.parse(
32
+ t_json,
33
+ :create_additions => true,
34
+ :match_string => { time_regexp => TestTime }
35
+ )
36
+ assert_equal [ t.strftime('%FT%T%z') ],
37
+ JSON.parse(
38
+ t_json,
39
+ :match_string => { time_regexp => TestTime }
40
+ )
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ $: << File.dirname(__FILE__)
2
+ $oj_dir = File.dirname(File.dirname(File.expand_path(File.dirname(__FILE__))))
3
+ %w(lib ext).each do |dir|
4
+ $: << File.join($oj_dir, dir)
5
+ end
6
+
7
+ require 'test/unit'
8
+ REAL_JSON_GEM = !!ENV['REAL_JSON_GEM']
9
+
10
+ if ENV['REAL_JSON_GEM']
11
+ require 'json'
12
+ else
13
+ require 'oj'
14
+ Oj.mimic_JSON
15
+ end
16
+
17
+ NaN = JSON::NaN if defined?(JSON::NaN)
18
+ NaN = 0.0/0 unless defined?(NaN)
@@ -0,0 +1,107 @@
1
+
2
+ class Perf
3
+
4
+ def initialize()
5
+ @items = []
6
+ end
7
+
8
+ def add(title, op, &blk)
9
+ @items << Item.new(title, op, &blk)
10
+ end
11
+
12
+ def before(title, &blk)
13
+ @items.each do |i|
14
+ if title == i.title
15
+ i.set_before(&blk)
16
+ break
17
+ end
18
+ end
19
+ end
20
+
21
+ def run(iter)
22
+ base = Item.new(nil, nil) { }
23
+ base.run(iter, 0.0)
24
+ @items.each do |i|
25
+ i.run(iter, base.duration)
26
+ if i.error.nil?
27
+ puts "#{i.title}.#{i.op} #{iter} times in %0.3f seconds or %0.3f #{i.op}/sec." % [i.duration, iter / i.duration]
28
+ else
29
+ puts "***** #{i.title}.#{i.op} failed! #{i.error}"
30
+ end
31
+ end
32
+ summary()
33
+ end
34
+
35
+ def summary()
36
+ fastest = nil
37
+ slowest = nil
38
+ width = 6
39
+ @items.each do |i|
40
+ next if i.duration.nil?
41
+ width = i.title.size if width < i.title.size
42
+ end
43
+ iva = @items.clone
44
+ iva.delete_if { |i| i.duration.nil? }
45
+ iva = iva.sort_by { |i| i.duration }
46
+ puts
47
+ puts "Summary:"
48
+ puts "%*s time (secs) rate (ops/sec)" % [width, 'System']
49
+ puts "#{'-' * width} ----------- --------------"
50
+ iva.each do |i|
51
+ if i.duration.nil?
52
+ else
53
+ puts "%*s %11.3f %14.3f" % [width, i.title, i.duration, i.rate ]
54
+ end
55
+ end
56
+ puts
57
+ puts "Comparison Matrix\n(performance factor, 2.0 means row is twice as fast as column)"
58
+ puts ([' ' * width] + iva.map { |i| "%*s" % [width, i.title] }).join(' ')
59
+ puts (['-' * width] + iva.map { |i| '-' * width }).join(' ')
60
+ iva.each do |i|
61
+ line = ["%*s" % [width, i.title]]
62
+ iva.each do |o|
63
+ line << "%*.2f" % [width, o.duration / i.duration]
64
+ end
65
+ puts line.join(' ')
66
+ end
67
+ puts
68
+ end
69
+
70
+ class Item
71
+ attr_accessor :title
72
+ attr_accessor :op
73
+ attr_accessor :blk
74
+ attr_accessor :duration
75
+ attr_accessor :rate
76
+ attr_accessor :error
77
+
78
+ def initialize(title, op, &blk)
79
+ @title = title
80
+ @blk = blk
81
+ @op = op
82
+ @duration = nil
83
+ @rate = nil
84
+ @error = nil
85
+ @before = nil
86
+ end
87
+
88
+ def set_before(&blk)
89
+ @before = blk
90
+ end
91
+
92
+ def run(iter, base)
93
+ begin
94
+ GC.start
95
+ @before.call unless @before.nil?
96
+ start = Time.now
97
+ iter.times { @blk.call }
98
+ @duration = Time.now - start - base
99
+ @duration = 0.0 if @duration < 0.0
100
+ @rate = iter / @duration
101
+ rescue Exception => e
102
+ @error = "#{e.class}: #{e.message}"
103
+ end
104
+ end
105
+
106
+ end # Item
107
+ end # Perf
@@ -0,0 +1,130 @@
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
@@ -0,0 +1,164 @@
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