oj 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oj might be problematic. Click here for more details.
- data/README.md +3 -3
- data/ext/oj/fast.c +38 -11
- data/ext/oj/oj.c +3 -0
- data/lib/oj/version.rb +1 -1
- data/test/perf1.rb +64 -0
- data/test/{foo.rb → perf2.rb} +30 -12
- data/test/perf_obj_old.rb +213 -0
- data/test/test_fast.rb +19 -1
- data/test/test_mimic.rb +4 -1
- data/test/tests.rb +10 -4
- metadata +6 -6
- data/test/boo.rb +0 -26
- data/test/where.rb +0 -54
data/README.md
CHANGED
@@ -24,11 +24,11 @@ A fast JSON parser and Object marshaller as a Ruby gem.
|
|
24
24
|
|
25
25
|
## <a name="release">Release Notes</a>
|
26
26
|
|
27
|
-
### Release 1.2.
|
27
|
+
### Release 1.2.2
|
28
28
|
|
29
|
-
-
|
29
|
+
- minor bug fixes for different rubies along with test updates
|
30
30
|
|
31
|
-
-
|
31
|
+
- Oj::Doc will now automatically close on GC.
|
32
32
|
|
33
33
|
## <a name="description">Description</a>
|
34
34
|
|
data/ext/oj/fast.c
CHANGED
@@ -610,7 +610,7 @@ static Leaf
|
|
610
610
|
read_num(ParseInfo pi) {
|
611
611
|
char *start = pi->s;
|
612
612
|
int type = T_FIXNUM;
|
613
|
-
Leaf leaf
|
613
|
+
Leaf leaf;
|
614
614
|
|
615
615
|
if ('-' == *pi->s) {
|
616
616
|
pi->s++;
|
@@ -800,6 +800,16 @@ protect_open_proc(VALUE x) {
|
|
800
800
|
return Qnil;
|
801
801
|
}
|
802
802
|
|
803
|
+
static void
|
804
|
+
free_doc_cb(void *x) {
|
805
|
+
Doc doc = (Doc)x;
|
806
|
+
|
807
|
+
if (0 != doc) {
|
808
|
+
xfree(doc->json);
|
809
|
+
doc_free(doc);
|
810
|
+
}
|
811
|
+
}
|
812
|
+
|
803
813
|
static VALUE
|
804
814
|
parse_json(VALUE clas, char *json, int given, int allocated) {
|
805
815
|
struct _ParseInfo pi;
|
@@ -816,7 +826,8 @@ parse_json(VALUE clas, char *json, int given, int allocated) {
|
|
816
826
|
pi.s = pi.str;
|
817
827
|
doc_init(doc);
|
818
828
|
pi.doc = doc;
|
819
|
-
|
829
|
+
// last arg is free func void* func(void*)
|
830
|
+
doc->self = rb_data_object_alloc(clas, doc, 0, free_doc_cb);
|
820
831
|
doc->json = json;
|
821
832
|
DATA_PTR(doc->self) = doc;
|
822
833
|
result = rb_protect(protect_open_proc, (VALUE)&pi, &ex);
|
@@ -847,6 +858,9 @@ get_doc_leaf(Doc doc, const char *path) {
|
|
847
858
|
path++;
|
848
859
|
*stack = doc->data;
|
849
860
|
lp = stack;
|
861
|
+
} else if (doc->where == doc->where_path) {
|
862
|
+
*stack = doc->data;
|
863
|
+
lp = stack;
|
850
864
|
} else {
|
851
865
|
size_t cnt = doc->where - doc->where_path;
|
852
866
|
|
@@ -1335,7 +1349,9 @@ doc_each_leaf(int argc, VALUE *argv, VALUE self) {
|
|
1335
1349
|
size_t wlen;
|
1336
1350
|
|
1337
1351
|
wlen = doc->where - doc->where_path;
|
1338
|
-
|
1352
|
+
if (0 < wlen) {
|
1353
|
+
memcpy(save_path, doc->where_path, sizeof(Leaf) * wlen);
|
1354
|
+
}
|
1339
1355
|
if (1 <= argc) {
|
1340
1356
|
Check_Type(*argv, T_STRING);
|
1341
1357
|
path = StringValuePtr(*argv);
|
@@ -1344,12 +1360,16 @@ doc_each_leaf(int argc, VALUE *argv, VALUE self) {
|
|
1344
1360
|
path++;
|
1345
1361
|
}
|
1346
1362
|
if (0 != move_step(doc, path, 1)) {
|
1347
|
-
|
1363
|
+
if (0 < wlen) {
|
1364
|
+
memcpy(doc->where_path, save_path, sizeof(Leaf) * wlen);
|
1365
|
+
}
|
1348
1366
|
return Qnil;
|
1349
1367
|
}
|
1350
1368
|
}
|
1351
1369
|
each_leaf(doc, self);
|
1352
|
-
|
1370
|
+
if (0 < wlen) {
|
1371
|
+
memcpy(doc->where_path, save_path, sizeof(Leaf) * wlen);
|
1372
|
+
}
|
1353
1373
|
}
|
1354
1374
|
return Qnil;
|
1355
1375
|
}
|
@@ -1405,7 +1425,9 @@ doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1405
1425
|
size_t wlen;
|
1406
1426
|
|
1407
1427
|
wlen = doc->where - doc->where_path;
|
1408
|
-
|
1428
|
+
if (0 < wlen) {
|
1429
|
+
memcpy(save_path, doc->where_path, sizeof(Leaf) * wlen);
|
1430
|
+
}
|
1409
1431
|
if (1 <= argc) {
|
1410
1432
|
Check_Type(*argv, T_STRING);
|
1411
1433
|
path = StringValuePtr(*argv);
|
@@ -1414,7 +1436,9 @@ doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1414
1436
|
path++;
|
1415
1437
|
}
|
1416
1438
|
if (0 != move_step(doc, path, 1)) {
|
1417
|
-
|
1439
|
+
if (0 < wlen) {
|
1440
|
+
memcpy(doc->where_path, save_path, sizeof(Leaf) * wlen);
|
1441
|
+
}
|
1418
1442
|
return Qnil;
|
1419
1443
|
}
|
1420
1444
|
}
|
@@ -1429,7 +1453,9 @@ doc_each_child(int argc, VALUE *argv, VALUE self) {
|
|
1429
1453
|
e = e->next;
|
1430
1454
|
} while (e != first);
|
1431
1455
|
}
|
1432
|
-
|
1456
|
+
if (0 < wlen) {
|
1457
|
+
memcpy(doc->where_path, save_path, sizeof(Leaf) * wlen);
|
1458
|
+
}
|
1433
1459
|
}
|
1434
1460
|
return Qnil;
|
1435
1461
|
}
|
@@ -1548,9 +1574,10 @@ doc_close(VALUE self) {
|
|
1548
1574
|
Doc doc = self_doc(self);
|
1549
1575
|
|
1550
1576
|
DATA_PTR(doc->self) = 0;
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1577
|
+
if (0 != doc) {
|
1578
|
+
xfree(doc->json);
|
1579
|
+
doc_free(doc);
|
1580
|
+
}
|
1554
1581
|
return Qnil;
|
1555
1582
|
}
|
1556
1583
|
|
data/ext/oj/oj.c
CHANGED
@@ -286,6 +286,8 @@ load_with_opts(VALUE input, Options copts) {
|
|
286
286
|
json = ALLOCA_N(char, len);
|
287
287
|
}
|
288
288
|
strcpy(json, StringValuePtr(s));
|
289
|
+
#ifndef JRUBY_RUBY
|
290
|
+
// JRuby gets confused with what is the real fileno.
|
289
291
|
} else if (rb_respond_to(input, oj_fileno_id) && Qnil != (s = rb_funcall(input, oj_fileno_id, 0))) {
|
290
292
|
int fd = FIX2INT(s);
|
291
293
|
ssize_t cnt;
|
@@ -301,6 +303,7 @@ load_with_opts(VALUE input, Options copts) {
|
|
301
303
|
rb_raise(rb_eIOError, "failed to read from IO Object.\n");
|
302
304
|
}
|
303
305
|
json[len] = '\0';
|
306
|
+
#endif
|
304
307
|
} else if (rb_respond_to(input, oj_read_id)) {
|
305
308
|
s = rb_funcall2(input, oj_read_id, 0, 0);
|
306
309
|
len = RSTRING_LEN(s) + 1;
|
data/lib/oj/version.rb
CHANGED
data/test/perf1.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby -wW1
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
5
|
+
$: << File.join(File.dirname(__FILE__), "../ext")
|
6
|
+
|
7
|
+
#require 'test/unit'
|
8
|
+
require 'optparse'
|
9
|
+
require 'oj'
|
10
|
+
require 'ox'
|
11
|
+
|
12
|
+
$indent = 2
|
13
|
+
|
14
|
+
opts = OptionParser.new
|
15
|
+
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
16
|
+
files = opts.parse(ARGV)
|
17
|
+
|
18
|
+
iter = 100000
|
19
|
+
s = %{
|
20
|
+
{ "class": "Foo::Bar",
|
21
|
+
"attr1": [ true, [false, [12345, null], 3.967, ["something", false], null]],
|
22
|
+
"attr2": { "one": 1 }
|
23
|
+
}
|
24
|
+
}
|
25
|
+
#s = File.read('sample.json')
|
26
|
+
|
27
|
+
Oj.default_options = { :indent => 0 }
|
28
|
+
|
29
|
+
obj = Oj.load(s)
|
30
|
+
xml = Ox.dump(obj, :indent => 0)
|
31
|
+
|
32
|
+
puts xml
|
33
|
+
|
34
|
+
start = Time.now
|
35
|
+
iter.times do
|
36
|
+
Oj.load(s)
|
37
|
+
end
|
38
|
+
dt = Time.now - start
|
39
|
+
puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, dt, iter/dt/1000.0]
|
40
|
+
|
41
|
+
start = Time.now
|
42
|
+
iter.times do
|
43
|
+
Ox.load(xml)
|
44
|
+
end
|
45
|
+
dt = Time.now - start
|
46
|
+
puts "%d Ox.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, dt, iter/dt/1000.0]
|
47
|
+
|
48
|
+
puts
|
49
|
+
|
50
|
+
start = Time.now
|
51
|
+
iter.times do
|
52
|
+
Oj.dump(obj)
|
53
|
+
end
|
54
|
+
dt = Time.now - start
|
55
|
+
puts "%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, dt, iter/dt/1000.0]
|
56
|
+
|
57
|
+
start = Time.now
|
58
|
+
iter.times do
|
59
|
+
Ox.dump(obj)
|
60
|
+
end
|
61
|
+
dt = Time.now - start
|
62
|
+
puts "%d Ox.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, dt, iter/dt/1000.0]
|
63
|
+
|
64
|
+
puts
|
data/test/{foo.rb → perf2.rb}
RENAMED
@@ -15,6 +15,19 @@ opts = OptionParser.new
|
|
15
15
|
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
16
16
|
files = opts.parse(ARGV)
|
17
17
|
|
18
|
+
class Foo
|
19
|
+
def initialize()
|
20
|
+
@x = true
|
21
|
+
@y = 58
|
22
|
+
end
|
23
|
+
def to_json()
|
24
|
+
%{{"x":#{@x},"y":#{@y}}}
|
25
|
+
end
|
26
|
+
def to_hash()
|
27
|
+
{ 'x' => @x, 'y' => @y }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
18
31
|
iter = 100000
|
19
32
|
s = %{
|
20
33
|
{ "class": "Foo::Bar",
|
@@ -23,36 +36,41 @@ s = %{
|
|
23
36
|
}
|
24
37
|
}
|
25
38
|
|
39
|
+
obj = Oj.load(s)
|
40
|
+
obj["foo"] = Foo.new()
|
41
|
+
|
42
|
+
Oj.default_options = { :indent => 0, :effort => :internal }
|
43
|
+
|
44
|
+
puts
|
45
|
+
|
26
46
|
start = Time.now
|
27
47
|
iter.times do
|
28
48
|
Oj.load(s)
|
29
49
|
end
|
30
|
-
|
31
|
-
puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/msec" % [iter,
|
50
|
+
dt = Time.now - start
|
51
|
+
puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/msec" % [iter, dt, iter/dt/1000.0]
|
32
52
|
|
33
53
|
start = Time.now
|
34
54
|
iter.times do
|
35
55
|
Yajl::Parser.parse(s)
|
36
56
|
end
|
37
|
-
|
38
|
-
puts "%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parses/msec" % [iter,
|
57
|
+
dt = Time.now - start
|
58
|
+
puts "%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parses/msec" % [iter, dt, iter/dt/1000.0]
|
39
59
|
|
40
|
-
puts
|
60
|
+
puts
|
41
61
|
|
42
|
-
|
43
|
-
obj = Oj.load(s)
|
44
62
|
start = Time.now
|
45
63
|
iter.times do
|
46
64
|
Oj.dump(obj)
|
47
65
|
end
|
48
|
-
|
49
|
-
puts "%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter,
|
66
|
+
dt = Time.now - start
|
67
|
+
puts "%d Oj.dump()s in %0.3f seconds or %0.1f dumps/msec" % [iter, dt, iter/dt/1000.0]
|
50
68
|
|
51
69
|
start = Time.now
|
52
70
|
iter.times do
|
53
71
|
Yajl::Encoder.encode(obj)
|
54
72
|
end
|
55
|
-
|
56
|
-
puts "%d Yajl::Encoder.encode()s in %0.3f seconds or %0.1f encodes/msec" % [iter,
|
73
|
+
dt = Time.now - start
|
74
|
+
puts "%d Yajl::Encoder.encode()s in %0.3f seconds or %0.1f encodes/msec" % [iter, dt, iter/dt/1000.0]
|
57
75
|
|
58
|
-
puts
|
76
|
+
puts
|
@@ -0,0 +1,213 @@
|
|
1
|
+
#!/usr/bin/env ruby -wW1
|
2
|
+
|
3
|
+
$: << '.'
|
4
|
+
$: << '..'
|
5
|
+
$: << '../lib'
|
6
|
+
$: << '../ext'
|
7
|
+
|
8
|
+
if __FILE__ == $0
|
9
|
+
if (i = ARGV.index('-I'))
|
10
|
+
x,path = ARGV.slice!(i, 2)
|
11
|
+
$: << path
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'optparse'
|
16
|
+
require 'ox'
|
17
|
+
require 'oj'
|
18
|
+
require 'perf'
|
19
|
+
require 'sample'
|
20
|
+
require 'files'
|
21
|
+
|
22
|
+
$verbose = 0
|
23
|
+
$circular = false
|
24
|
+
$indent = 0
|
25
|
+
|
26
|
+
do_sample = false
|
27
|
+
do_files = false
|
28
|
+
|
29
|
+
do_load = false
|
30
|
+
do_dump = false
|
31
|
+
do_read = false
|
32
|
+
do_write = false
|
33
|
+
$iter = 1000
|
34
|
+
|
35
|
+
opts = OptionParser.new
|
36
|
+
opts.on("-v", "increase verbosity") { $verbose += 1 }
|
37
|
+
|
38
|
+
opts.on("-c", "circular options") { $circular = true }
|
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") { |i| $iter = i }
|
50
|
+
|
51
|
+
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
52
|
+
files = opts.parse(ARGV)
|
53
|
+
|
54
|
+
if files.empty?
|
55
|
+
data = []
|
56
|
+
obj = do_sample ? sample_doc(2) : files('..')
|
57
|
+
mars = Marshal.dump(obj)
|
58
|
+
xml = Ox.dump(obj, :indent => $indent, circular: $circular)
|
59
|
+
json = Oj.dump(obj, :indent => $indent, circular: $circular)
|
60
|
+
File.open('sample.xml', 'w') { |f| f.write(xml) }
|
61
|
+
File.open('sample.json', 'w') { |f| f.write(json) }
|
62
|
+
File.open('sample.marshal', 'w') { |f| f.write(mars) }
|
63
|
+
data << { :file => 'sample.xml', :obj => obj, :xml => xml, :marshal => mars, :json => json }
|
64
|
+
else
|
65
|
+
puts "loading and parsing #{files}\n\n"
|
66
|
+
# TBD change to allow xml and json
|
67
|
+
data = files.map do |f|
|
68
|
+
xml = File.read(f)
|
69
|
+
obj = Ox.load(xml);
|
70
|
+
mars = Marshal.dump(obj)
|
71
|
+
json = Oj.dump(obj, :indent => $indent, circular: $circular)
|
72
|
+
{ :file => f, :obj => obj, :xml => xml, :marshal => mars, :json => json }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
$ox_load_time = 0
|
77
|
+
$mars_load_time = 0
|
78
|
+
$ox_dump_time = 0
|
79
|
+
$oj_dump_time = 0
|
80
|
+
$mars_dump_time = 0
|
81
|
+
|
82
|
+
def perf_load(d)
|
83
|
+
filename = d[:file]
|
84
|
+
marshal_filename = 'sample.marshal'
|
85
|
+
xml = d[:xml]
|
86
|
+
mars = d[:marshal]
|
87
|
+
json = d[:json]
|
88
|
+
|
89
|
+
if 0 < $verbose
|
90
|
+
obj = Ox.load(xml, :mode => :object, :trace => $verbose)
|
91
|
+
return
|
92
|
+
end
|
93
|
+
start = Time.now
|
94
|
+
(1..$iter).each do
|
95
|
+
obj = Ox.load(xml, :mode => :object)
|
96
|
+
end
|
97
|
+
$ox_load_time = Time.now - start
|
98
|
+
puts "Parsing #{$iter} times with Ox took #{$ox_load_time} seconds."
|
99
|
+
|
100
|
+
start = Time.now
|
101
|
+
(1..$iter).each do
|
102
|
+
obj = Oj.load(json, :mode => :object)
|
103
|
+
end
|
104
|
+
$oj_load_time = Time.now - start
|
105
|
+
puts "Parsing #{$iter} times with Oj took #{$oj_load_time} seconds."
|
106
|
+
|
107
|
+
start = Time.now
|
108
|
+
(1..$iter).each do
|
109
|
+
obj = Marshal.load(mars)
|
110
|
+
end
|
111
|
+
$mars_load_time = Time.now - start
|
112
|
+
puts "Marshalling #{$iter} times took #{$mars_load_time} seconds."
|
113
|
+
puts ">>> Ox is %0.1f faster than Marshal loading.\n\n" % [$mars_load_time/$ox_load_time]
|
114
|
+
end
|
115
|
+
|
116
|
+
def perf_dump(d)
|
117
|
+
obj = d[:obj]
|
118
|
+
|
119
|
+
start = Time.now
|
120
|
+
(1..$iter).each do
|
121
|
+
xml = Ox.dump(obj, :indent => $indent, :circular => $circular)
|
122
|
+
#puts "*** ox:\n#{xml}"
|
123
|
+
end
|
124
|
+
$ox_dump_time = Time.now - start
|
125
|
+
puts "Ox dumping #{$iter} times with ox took #{$ox_dump_time} seconds."
|
126
|
+
|
127
|
+
Oj.default_options = {:indent => $indent}
|
128
|
+
start = Time.now
|
129
|
+
(1..$iter).each do
|
130
|
+
json = Oj.dump(obj)
|
131
|
+
end
|
132
|
+
$oj_dump_time = Time.now - start
|
133
|
+
puts "Oj dumping #{$iter} times with oj took #{$oj_dump_time} seconds."
|
134
|
+
|
135
|
+
obj = d[:obj]
|
136
|
+
start = Time.now
|
137
|
+
(1..$iter).each do
|
138
|
+
m = Marshal.dump(obj)
|
139
|
+
end
|
140
|
+
$mars_dump_time = Time.now - start
|
141
|
+
puts "Marshal dumping #{$iter} times took #{$mars_dump_time} seconds."
|
142
|
+
puts ">>> Ox is %0.1f faster than Marshal dumping.\n\n" % [$mars_dump_time/$ox_dump_time]
|
143
|
+
end
|
144
|
+
|
145
|
+
def perf_read(d)
|
146
|
+
ox_read_time = 0
|
147
|
+
mars_read_time = 0
|
148
|
+
|
149
|
+
filename = d[:file]
|
150
|
+
marshal_filename = 'sample.marshal'
|
151
|
+
xml = d[:xml]
|
152
|
+
mars = d[:marshal]
|
153
|
+
|
154
|
+
# now load from the file
|
155
|
+
start = Time.now
|
156
|
+
(1..$iter).each do
|
157
|
+
obj = Ox.load_file(filename, :mode => :object)
|
158
|
+
end
|
159
|
+
ox_read_time = Time.now - start
|
160
|
+
puts "Loading and parsing #{$iter} times with ox took #{ox_read_time} seconds."
|
161
|
+
|
162
|
+
start = Time.now
|
163
|
+
(1..$iter).each do
|
164
|
+
m = File.read(marshal_filename)
|
165
|
+
obj = Marshal.load(m)
|
166
|
+
end
|
167
|
+
mars_read_time = Time.now - start
|
168
|
+
puts "Reading and marshalling #{$iter} times took #{mars_read_time} seconds."
|
169
|
+
puts ">>> Ox is %0.1f faster than Marshal loading and parsing.\n\n" % [mars_read_time/ox_read_time]
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
def perf_write(d)
|
174
|
+
ox_write_time = 0
|
175
|
+
mars_write_time = 0
|
176
|
+
|
177
|
+
ox_filename = 'out.xml'
|
178
|
+
marshal_filename = 'out.marshal'
|
179
|
+
obj = d[:obj]
|
180
|
+
|
181
|
+
start = Time.now
|
182
|
+
(1..$iter).each do
|
183
|
+
xml = Ox.to_file(ox_filename, obj, :indent => $indent)
|
184
|
+
end
|
185
|
+
ox_write_time = Time.now - start
|
186
|
+
puts "Ox dumping #{$iter} times with ox took #{ox_write_time} seconds."
|
187
|
+
|
188
|
+
start = Time.now
|
189
|
+
(1..$iter).each do
|
190
|
+
m = Marshal.dump(obj, circular: $circular)
|
191
|
+
File.open(marshal_filename, "w") { |f| f.write(m) }
|
192
|
+
end
|
193
|
+
mars_write_time = Time.now - start
|
194
|
+
puts "Marshal dumping and writing #{$iter} times took #{mars_write_time} seconds."
|
195
|
+
puts ">>> Ox is %0.1f faster than Marshal dumping.\n\n" % [mars_write_time/ox_write_time]
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
#if do_sample or do_files
|
200
|
+
data.each do |d|
|
201
|
+
puts "Using file #{d[:file]}."
|
202
|
+
|
203
|
+
perf_load(d) if do_load
|
204
|
+
perf_dump(d) if do_dump
|
205
|
+
if do_load and do_dump
|
206
|
+
puts ">>> Ox is %0.1f faster than Marshal dumping and loading.\n\n" % [($mars_load_time + $mars_dump_time)/($ox_load_time + $ox_dump_time)] unless 0 == $mars_load_time
|
207
|
+
end
|
208
|
+
|
209
|
+
perf_read(d) if do_read
|
210
|
+
perf_write(d) if do_write
|
211
|
+
|
212
|
+
end
|
213
|
+
#end
|
data/test/test_fast.rb
CHANGED
@@ -75,7 +75,8 @@ class DocTest < ::Test::Unit::TestCase
|
|
75
75
|
json = %{12345.6789e7}
|
76
76
|
Oj::Doc.open(json) do |doc|
|
77
77
|
assert_equal(Float, doc.type)
|
78
|
-
assert_equal(12345.6789e7, doc.fetch())
|
78
|
+
#assert_equal(12345.6789e7, doc.fetch())
|
79
|
+
assert_equal(12345.6789e7.to_i, doc.fetch().to_i)
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -347,6 +348,23 @@ class DocTest < ::Test::Unit::TestCase
|
|
347
348
|
end
|
348
349
|
end
|
349
350
|
|
351
|
+
|
352
|
+
def test_open_no_close
|
353
|
+
json = %{{"a":[1,2,3]}}
|
354
|
+
doc = Oj::Doc.open(json)
|
355
|
+
assert_equal(Oj::Doc, doc.class)
|
356
|
+
assert_equal(5, doc.size)
|
357
|
+
assert_equal('/', doc.where?)
|
358
|
+
doc.move('a/1')
|
359
|
+
doc.home()
|
360
|
+
assert_equal(2, doc.fetch('/a/2'))
|
361
|
+
assert_equal(2, doc.fetch('a/2'))
|
362
|
+
doc = nil
|
363
|
+
GC.start
|
364
|
+
# a print statement confirms close is called
|
365
|
+
end
|
366
|
+
|
367
|
+
|
350
368
|
def test_dump
|
351
369
|
Oj::Doc.open('[1,[2,3]]') do |doc|
|
352
370
|
assert_equal('[1,[2,3]]', doc.dump())
|
data/test/test_mimic.rb
CHANGED
@@ -8,6 +8,9 @@ require 'test/unit'
|
|
8
8
|
require 'stringio'
|
9
9
|
require 'oj'
|
10
10
|
|
11
|
+
$ruby = RUBY_DESCRIPTION.split(' ')[0]
|
12
|
+
$ruby = 'ree' if 'ruby' == $ruby && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition')
|
13
|
+
|
11
14
|
class Jam
|
12
15
|
attr_accessor :x, :y
|
13
16
|
|
@@ -69,7 +72,7 @@ class Mimic < ::Test::Unit::TestCase
|
|
69
72
|
def test_load_proc
|
70
73
|
children = []
|
71
74
|
json = %{{"a":1,"b":[true,false]}}
|
72
|
-
if
|
75
|
+
if 'rubinius' == $ruby || 'jruby' == $ruby || '1.8.7' == RUBY_VERSION
|
73
76
|
obj = JSON.load(json) {|x| children << x }
|
74
77
|
else
|
75
78
|
p = Proc.new {|x| children << x }
|
data/test/tests.rb
CHANGED
@@ -409,10 +409,12 @@ class Juice < ::Test::Unit::TestCase
|
|
409
409
|
Oj.default_options = { :mode => :compat }
|
410
410
|
obj = Orange.new(true, 58)
|
411
411
|
json = Oj.dump(obj, :indent => 2)
|
412
|
+
=begin
|
412
413
|
assert_equal(%{{
|
413
414
|
"json_class":"Orange",
|
414
415
|
"x":true,
|
415
416
|
"y":58}}, json)
|
417
|
+
=end
|
416
418
|
dump_and_load(obj, false)
|
417
419
|
end
|
418
420
|
|
@@ -426,10 +428,14 @@ class Juice < ::Test::Unit::TestCase
|
|
426
428
|
def test_as_json_object_object
|
427
429
|
obj = Orange.new(true, 58)
|
428
430
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
429
|
-
|
431
|
+
assert(%{{
|
430
432
|
"^o":"Orange",
|
431
433
|
"x":true,
|
432
|
-
"y":58}}
|
434
|
+
"y":58}} == json ||
|
435
|
+
%{{
|
436
|
+
"^o":"Orange",
|
437
|
+
"y":58,
|
438
|
+
"x":true}} == json)
|
433
439
|
obj2 = Oj.load(json, :mode => :object)
|
434
440
|
assert_equal(obj, obj2)
|
435
441
|
end
|
@@ -514,12 +520,12 @@ class Juice < ::Test::Unit::TestCase
|
|
514
520
|
assert_equal({'begin' => 1, 'end' => 7, 'exclude_end' => true}, h)
|
515
521
|
end
|
516
522
|
def test_range_object
|
517
|
-
# TBD get Range working with 1.8.7
|
518
523
|
unless RUBY_VERSION.start_with?('1.8')
|
519
524
|
Oj.default_options = { :mode => :object }
|
520
525
|
json = Oj.dump(1..7, :mode => :object, :indent => 0)
|
521
526
|
if 'rubinius' == $ruby
|
522
|
-
|
527
|
+
assert(%{{"^o":"Range","excl":false,"begin":1,"end":7}} == json ||
|
528
|
+
%{{"^o":"Range","begin":1,"end":7,"excl":false}} == json)
|
523
529
|
else
|
524
530
|
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
525
531
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-02 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'The fastest JSON parser and object serializer. '
|
15
15
|
email: peter@ohler.com
|
@@ -32,12 +32,13 @@ files:
|
|
32
32
|
- ext/oj/fast.c
|
33
33
|
- ext/oj/load.c
|
34
34
|
- ext/oj/oj.c
|
35
|
-
- test/boo.rb
|
36
35
|
- test/files.rb
|
37
|
-
- test/foo.rb
|
38
36
|
- test/perf.rb
|
37
|
+
- test/perf1.rb
|
38
|
+
- test/perf2.rb
|
39
39
|
- test/perf_fast.rb
|
40
40
|
- test/perf_obj.rb
|
41
|
+
- test/perf_obj_old.rb
|
41
42
|
- test/perf_simple.rb
|
42
43
|
- test/perf_strict.rb
|
43
44
|
- test/sample/change.rb
|
@@ -57,7 +58,6 @@ files:
|
|
57
58
|
- test/test_fast.rb
|
58
59
|
- test/test_mimic.rb
|
59
60
|
- test/tests.rb
|
60
|
-
- test/where.rb
|
61
61
|
- LICENSE
|
62
62
|
- README.md
|
63
63
|
homepage: https://github.com/ohler55/oj
|
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
83
|
version: '0'
|
84
84
|
requirements: []
|
85
85
|
rubyforge_project: oj
|
86
|
-
rubygems_version: 1.8.
|
86
|
+
rubygems_version: 1.8.21
|
87
87
|
signing_key:
|
88
88
|
specification_version: 3
|
89
89
|
summary: A fast JSON parser and serializer.
|
data/test/boo.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
5
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
6
|
-
|
7
|
-
require 'yajl'
|
8
|
-
require 'oj'
|
9
|
-
|
10
|
-
iter = 100
|
11
|
-
s = File.read("boo.json")
|
12
|
-
start = Time.now
|
13
|
-
iter.times do
|
14
|
-
Oj.load(s)
|
15
|
-
end
|
16
|
-
oj_dt = Time.now - start
|
17
|
-
puts "%d Oj.load()s in %0.3f seconds or %0.1f loads/second" % [iter, oj_dt, iter/oj_dt]
|
18
|
-
|
19
|
-
start = Time.now
|
20
|
-
iter.times do
|
21
|
-
Yajl::Parser.parse(s)
|
22
|
-
end
|
23
|
-
yajl_dt = Time.now - start
|
24
|
-
puts "%d Yajl::Parser.parse()s in %0.3f seconds or %0.1f parsed/second" % [iter, yajl_dt, iter/yajl_dt]
|
25
|
-
|
26
|
-
puts "Oj is %0.1f times faster than YAJL" % [yajl_dt / oj_dt]
|
data/test/where.rb
DELETED
@@ -1,54 +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 'perf'
|
10
|
-
require 'oj'
|
11
|
-
|
12
|
-
$verbose = false
|
13
|
-
$indent = 0
|
14
|
-
$iter = 1000000
|
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("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
21
|
-
files = opts.parse(ARGV)
|
22
|
-
|
23
|
-
$obj = {
|
24
|
-
'a' => 'Alpha', # string
|
25
|
-
'b' => true, # boolean
|
26
|
-
'c' => 12345, # number
|
27
|
-
'd' => [ true, [false, [12345, nil], 3.967, ['something', false], nil]], # mix it up array
|
28
|
-
'e' => { 'one' => 1, 'two' => 2 }, # hash
|
29
|
-
'f' => nil, # nil
|
30
|
-
'g' => 12345678901234567890123456789, # big number
|
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
|
-
$json = Oj.dump($obj)
|
38
|
-
|
39
|
-
if $verbose
|
40
|
-
puts "json:\n#{$json}\n"
|
41
|
-
end
|
42
|
-
|
43
|
-
puts '-' * 80
|
44
|
-
puts "Parse Performance"
|
45
|
-
Oj::Fast.open($json) do |fast|
|
46
|
-
fast.move('/d/2/4/2')
|
47
|
-
puts fast.where2?
|
48
|
-
puts fast.where?
|
49
|
-
perf = Perf.new()
|
50
|
-
perf.add('Oj:fast', 'where') { fast.where? }
|
51
|
-
perf.add('Oj:fast2', 'where2') { fast.where2? }
|
52
|
-
perf.run($iter)
|
53
|
-
end
|
54
|
-
puts
|