oj 2.1.2 → 2.1.3
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.
- checksums.yaml +4 -4
- data/README.md +3 -23
- data/ext/oj/dump.c +0 -1
- data/ext/oj/hash.c +1 -0
- data/ext/oj/hash_test.c +8 -2
- data/ext/oj/object.c +19 -0
- data/ext/oj/oj.c +28 -3
- data/ext/oj/val_stack.h +1 -0
- data/lib/oj/version.rb +1 -1
- metadata +2 -38
- data/test/a.rb +0 -38
- data/test/bug.rb +0 -15
- data/test/files.rb +0 -29
- data/test/foo.rb +0 -24
- data/test/mj.rb +0 -48
- data/test/perf.rb +0 -107
- data/test/perf_compat.rb +0 -128
- data/test/perf_fast.rb +0 -164
- data/test/perf_object.rb +0 -136
- data/test/perf_saj.rb +0 -109
- data/test/perf_scp.rb +0 -151
- data/test/perf_simple.rb +0 -287
- data/test/perf_strict.rb +0 -127
- data/test/sample.rb +0 -55
- data/test/sample/change.rb +0 -14
- data/test/sample/dir.rb +0 -19
- data/test/sample/doc.rb +0 -36
- data/test/sample/file.rb +0 -48
- data/test/sample/group.rb +0 -16
- data/test/sample/hasprops.rb +0 -16
- data/test/sample/layer.rb +0 -12
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -10
- data/test/sample/shape.rb +0 -35
- data/test/sample/text.rb +0 -20
- data/test/sample_json.rb +0 -37
- data/test/test_compat.rb +0 -342
- data/test/test_fast.rb +0 -416
- data/test/test_mimic.rb +0 -208
- data/test/test_mimic_after.rb +0 -35
- data/test/test_object.rb +0 -390
- data/test/test_saj.rb +0 -184
- data/test/test_scp.rb +0 -224
- data/test/test_strict.rb +0 -259
- data/test/tests.rb +0 -1017
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f2645663d6b76de56402dc004a41b2299c3eb09
|
4
|
+
data.tar.gz: 2df5a5fdca36bb28f69130f249500cbe7ea9a148
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8b3d8d7a4437b06cb2b7c509042bcd83f5ad6af6dba92e05b40af29b49d89b98608ffcb0668807201ce152b13ca702276bcf8492afe04adb2a8594bafcfecc0
|
7
|
+
data.tar.gz: 3daeb161d0402dcdbffd7aad76551ae39203e9b797fcff261d32c8b38a63d175c270e1f0ad7f9e2db6fbd86af5de81f564cac5e9415a74a7f84e2f2f29a6c01c
|
data/README.md
CHANGED
@@ -20,31 +20,11 @@ Follow [@peterohler on Twitter](http://twitter.com/#!/peterohler) for announceme
|
|
20
20
|
|
21
21
|
[![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
|
22
22
|
|
23
|
-
### Current Release 2.1.
|
23
|
+
### Current Release 2.1.3
|
24
24
|
|
25
|
-
- Fixed
|
25
|
+
- Fixed bug that did not deserialize all attributes in an Exception subclass.
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
- Fixed off by 1 error in buffer for escaped strings.
|
30
|
-
|
31
|
-
### Current Release 2.1.0
|
32
|
-
|
33
|
-
- This version is a major rewrite of the parser. The parser now uses a constant
|
34
|
-
stack size no matter how deeply nested the JSON document is. The parser is
|
35
|
-
also slightly faster for larger documents and 30% faster for object parsing.
|
36
|
-
|
37
|
-
- Oj.strict_load() was renamed to Oj.safe_load() to better represent its
|
38
|
-
functionality. A new Oj.strict_load() is simply Oj.load() with :mode set to
|
39
|
-
:strict.
|
40
|
-
|
41
|
-
- Oj.compat_load() and Oj.object_load() added.
|
42
|
-
|
43
|
-
- A new Simple Callback Parser was added invoked by Oj.sc_parse().
|
44
|
-
|
45
|
-
- Eliminated :max_stack option as it is no longer needed.
|
46
|
-
|
47
|
-
- Handle cleanup after exceptions better.
|
27
|
+
- Added a sample to demonstrate how to write Exception subclasses that will automatically serialize and deserialize.
|
48
28
|
|
49
29
|
[Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
|
50
30
|
|
data/ext/oj/dump.c
CHANGED
data/ext/oj/hash.c
CHANGED
data/ext/oj/hash_test.c
CHANGED
@@ -28,11 +28,16 @@
|
|
28
28
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
*/
|
30
30
|
|
31
|
+
// if windows, comment out the whole file. It's only a performance test.
|
31
32
|
#ifndef _WIN32
|
32
33
|
#include <sys/time.h>
|
33
34
|
#include <time.h>
|
34
|
-
#endif
|
35
35
|
#include "hash.h"
|
36
|
+
#include <stdint.h>
|
37
|
+
|
38
|
+
/* Define printf formats for standard types, like PRIu64 for uint64_t. */
|
39
|
+
#define __STDC_FORMAT_MACROS
|
40
|
+
#include <inttypes.h>
|
36
41
|
|
37
42
|
typedef struct _StrLen {
|
38
43
|
const char *str;
|
@@ -473,7 +478,7 @@ perf() {
|
|
473
478
|
#if IS_WINDOWS
|
474
479
|
printf("%d iterations took %ld msecs\n", iter, (long)(dt / 1000));
|
475
480
|
#else
|
476
|
-
printf("%d iterations took %
|
481
|
+
printf("%d iterations took %"PRIu64" msecs\n", iter, dt / 1000);
|
477
482
|
#endif
|
478
483
|
}
|
479
484
|
|
@@ -505,3 +510,4 @@ oj_hash_test() {
|
|
505
510
|
oj_hash_print();
|
506
511
|
perf();
|
507
512
|
}
|
513
|
+
#endif
|
data/ext/oj/object.c
CHANGED
@@ -241,6 +241,23 @@ hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, VALUE value) {
|
|
241
241
|
return 0;
|
242
242
|
}
|
243
243
|
|
244
|
+
static void
|
245
|
+
copy_ivars(VALUE target, VALUE src) {
|
246
|
+
VALUE vars = rb_funcall(src, oj_instance_variables_id, 0);
|
247
|
+
VALUE *np = RARRAY_PTR(vars);
|
248
|
+
ID vid;
|
249
|
+
int i, cnt = (int)RARRAY_LEN(vars);
|
250
|
+
const char *attr;
|
251
|
+
|
252
|
+
for (i = cnt; 0 < i; i--, np++) {
|
253
|
+
vid = rb_to_id(*np);
|
254
|
+
attr = rb_id2name(vid);
|
255
|
+
if ('@' == *attr) {
|
256
|
+
rb_ivar_set(target, vid, rb_ivar_get(src, vid));
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
244
261
|
static void
|
245
262
|
set_obj_ivar(Val parent, const char *key, size_t klen, VALUE value) {
|
246
263
|
ID var_id;
|
@@ -249,9 +266,11 @@ set_obj_ivar(Val parent, const char *key, size_t klen, VALUE value) {
|
|
249
266
|
if ('~' == *key && Qtrue == rb_obj_is_kind_of(parent->val, rb_eException)) {
|
250
267
|
if (5 == klen && 0 == strncmp("~mesg", key, klen)) {
|
251
268
|
VALUE args[1];
|
269
|
+
VALUE prev = parent->val;
|
252
270
|
|
253
271
|
args[0] = value;
|
254
272
|
parent->val = rb_class_new_instance(1, args, rb_class_of(parent->val));
|
273
|
+
copy_ivars(parent->val, prev);
|
255
274
|
} else if (3 == klen && 0 == strncmp("~bt", key, klen)) {
|
256
275
|
rb_funcall(parent->val, rb_intern("set_backtrace"), 1, value);
|
257
276
|
}
|
data/ext/oj/oj.c
CHANGED
@@ -462,6 +462,22 @@ oj_parse_options(VALUE ropts, Options copts) {
|
|
462
462
|
* valid. If the input is not a valid JSON document (an empty string is not a
|
463
463
|
* valid JSON document) an exception is raised.
|
464
464
|
*
|
465
|
+
* Note: Oj is not able to automatically deserialize all classes that are a
|
466
|
+
* subclass of a Ruby Exception. Only exception that take one required string
|
467
|
+
* argument in the initialize() method are supported. This is an example of how
|
468
|
+
* to write an Exception subclass that supports both a single string intializer
|
469
|
+
* and an Exception as an argument. Additional optional arguments can be added
|
470
|
+
* as well.
|
471
|
+
*
|
472
|
+
* The reason for this restriction has to do with a design decision on the part
|
473
|
+
* of the Ruby developers. Exceptions are special Objects. They do not follow the
|
474
|
+
* rules of other Objects. Exceptions have 'mesg' and a 'bt' attribute. Note that
|
475
|
+
* these are not '@mesg' and '@bt'. They can not be set using the normal C or
|
476
|
+
* Ruby calls. The only way I have found to set the 'mesg' attribute is through
|
477
|
+
* the initializer. Unfortunately that means any subclass that provides a
|
478
|
+
* different initializer can not be automatically decoded. A way around this is
|
479
|
+
* to use a create function but this example shows an alternative.
|
480
|
+
*
|
465
481
|
* @param [String|IO] json JSON String or an Object that responds to read()
|
466
482
|
* @param [Hash] options load options (same as default_options)
|
467
483
|
*/
|
@@ -1046,6 +1062,16 @@ define_mimic_json(int argc, VALUE *argv, VALUE self) {
|
|
1046
1062
|
return mimic;
|
1047
1063
|
}
|
1048
1064
|
|
1065
|
+
/*
|
1066
|
+
extern void oj_hash_test();
|
1067
|
+
|
1068
|
+
static VALUE
|
1069
|
+
hash_test(VALUE self) {
|
1070
|
+
oj_hash_test();
|
1071
|
+
return Qnil;
|
1072
|
+
}
|
1073
|
+
*/
|
1074
|
+
|
1049
1075
|
void Init_oj() {
|
1050
1076
|
Oj = rb_define_module("Oj");
|
1051
1077
|
|
@@ -1054,6 +1080,8 @@ void Init_oj() {
|
|
1054
1080
|
rb_require("bigdecimal");
|
1055
1081
|
rb_require("stringio");
|
1056
1082
|
|
1083
|
+
//rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1084
|
+
|
1057
1085
|
rb_define_module_function(Oj, "default_options", get_def_opts, 0);
|
1058
1086
|
rb_define_module_function(Oj, "default_options=", set_def_opts, 1);
|
1059
1087
|
|
@@ -1140,9 +1168,6 @@ void Init_oj() {
|
|
1140
1168
|
pthread_mutex_init(&oj_cache_mutex, 0);
|
1141
1169
|
#endif
|
1142
1170
|
oj_init_doc();
|
1143
|
-
|
1144
|
-
//rb_define_module_function(Oj, "hash_test", hash_test, 0);
|
1145
|
-
|
1146
1171
|
}
|
1147
1172
|
|
1148
1173
|
// mimic JSON documentation
|
data/ext/oj/val_stack.h
CHANGED
data/lib/oj/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'The fastest JSON parser and object serializer. '
|
14
14
|
email: peter@ohler.com
|
@@ -53,42 +53,6 @@ files:
|
|
53
53
|
- ext/oj/scp.c
|
54
54
|
- ext/oj/strict.c
|
55
55
|
- ext/oj/val_stack.c
|
56
|
-
- test/a.rb
|
57
|
-
- test/bug.rb
|
58
|
-
- test/files.rb
|
59
|
-
- test/foo.rb
|
60
|
-
- test/mj.rb
|
61
|
-
- test/perf.rb
|
62
|
-
- test/perf_compat.rb
|
63
|
-
- test/perf_fast.rb
|
64
|
-
- test/perf_object.rb
|
65
|
-
- test/perf_saj.rb
|
66
|
-
- test/perf_scp.rb
|
67
|
-
- test/perf_simple.rb
|
68
|
-
- test/perf_strict.rb
|
69
|
-
- test/sample/change.rb
|
70
|
-
- test/sample/dir.rb
|
71
|
-
- test/sample/doc.rb
|
72
|
-
- test/sample/file.rb
|
73
|
-
- test/sample/group.rb
|
74
|
-
- test/sample/hasprops.rb
|
75
|
-
- test/sample/layer.rb
|
76
|
-
- test/sample/line.rb
|
77
|
-
- test/sample/oval.rb
|
78
|
-
- test/sample/rect.rb
|
79
|
-
- test/sample/shape.rb
|
80
|
-
- test/sample/text.rb
|
81
|
-
- test/sample.rb
|
82
|
-
- test/sample_json.rb
|
83
|
-
- test/test_compat.rb
|
84
|
-
- test/test_fast.rb
|
85
|
-
- test/test_mimic.rb
|
86
|
-
- test/test_mimic_after.rb
|
87
|
-
- test/test_object.rb
|
88
|
-
- test/test_saj.rb
|
89
|
-
- test/test_scp.rb
|
90
|
-
- test/test_strict.rb
|
91
|
-
- test/tests.rb
|
92
56
|
- LICENSE
|
93
57
|
- README.md
|
94
58
|
homepage: http://www.ohler.com/oj
|
data/test/a.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$: << File.dirname(__FILE__)
|
5
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
6
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
7
|
-
|
8
|
-
require 'pp'
|
9
|
-
require 'oj'
|
10
|
-
require 'perf'
|
11
|
-
|
12
|
-
obj = [[1],[2],[3],[4],[5],[6],[7],[8],[9]]
|
13
|
-
obj = [[],[],[],[],[],[],[],[],[]]
|
14
|
-
obj = {
|
15
|
-
'a' => 'Alpha', # string
|
16
|
-
'b' => true, # boolean
|
17
|
-
'c' => 12345, # number
|
18
|
-
'd' => [ true, [false, [12345, nil], 3.967, ['something', false], nil]], # mix it up array
|
19
|
-
'e' => { 'one' => 1, 'two' => 2 }, # hash
|
20
|
-
'f' => nil, # nil
|
21
|
-
'g' => 12345678901234567890123456789, # big number
|
22
|
-
'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
|
23
|
-
'i' => [[[[[[[nil]]]]]]] # deep array, again, not that deep
|
24
|
-
}
|
25
|
-
|
26
|
-
json = Oj.dump(obj, mode: :compat)
|
27
|
-
|
28
|
-
puts json
|
29
|
-
#pp Oj.saj_parse(nil, json)
|
30
|
-
pp Oj.t_parse(json)
|
31
|
-
|
32
|
-
if true
|
33
|
-
perf = Perf.new()
|
34
|
-
perf.add('SAJ', 'oj') { Oj.saj_parse(nil, json) }
|
35
|
-
perf.add('T', 'oj') { Oj.t_parse(json) }
|
36
|
-
perf.add('load', 'oj') { Oj.load(json) }
|
37
|
-
perf.run(10000)
|
38
|
-
end
|
data/test/bug.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
# Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
|
5
|
-
# required. That can be set in the RUBYOPT environment variable.
|
6
|
-
# export RUBYOPT=-w
|
7
|
-
|
8
|
-
$VERBOSE = true
|
9
|
-
|
10
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
11
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
12
|
-
|
13
|
-
require 'oj'
|
14
|
-
|
15
|
-
Oj.load_file('josh2.json', :mode => :strict)
|
data/test/files.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW2
|
2
|
-
|
3
|
-
if $0 == __FILE__
|
4
|
-
$: << '.'
|
5
|
-
$: << '..'
|
6
|
-
$: << '../lib'
|
7
|
-
$: << '../ext'
|
8
|
-
end
|
9
|
-
|
10
|
-
require 'pp'
|
11
|
-
require 'sample/file'
|
12
|
-
require 'sample/dir'
|
13
|
-
|
14
|
-
def files(dir)
|
15
|
-
d = ::Sample::Dir.new(dir)
|
16
|
-
Dir.new(dir).each do |fn|
|
17
|
-
next if fn.start_with?('.')
|
18
|
-
filename = File.join(dir, fn)
|
19
|
-
#filename = '.' == dir ? fn : File.join(dir, fn)
|
20
|
-
if File.directory?(filename)
|
21
|
-
d << files(filename)
|
22
|
-
else
|
23
|
-
d << ::Sample::File.new(filename)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
#pp d
|
27
|
-
d
|
28
|
-
end
|
29
|
-
|
data/test/foo.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
# Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
|
5
|
-
# required. That can be set in the RUBYOPT environment variable.
|
6
|
-
# export RUBYOPT=-w
|
7
|
-
|
8
|
-
$VERBOSE = true
|
9
|
-
|
10
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
11
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
12
|
-
|
13
|
-
require 'oj'
|
14
|
-
|
15
|
-
reltypes={}
|
16
|
-
Oj::Doc.open_file('foo.json') do |doc|
|
17
|
-
doc.each_child do |target|
|
18
|
-
puts "#{target.local_key} is #{target.local_key.class}"
|
19
|
-
target.each_leaf do |score|
|
20
|
-
reltype=score.local_key
|
21
|
-
reltypes[reltype] = (reltypes[reltype] || 0) + 1
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/test/mj.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
5
|
-
$: << File.join(File.dirname(__FILE__), "../ext")
|
6
|
-
# $: << File.join(File.dirname(__FILE__), "../../multi_json/lib")
|
7
|
-
|
8
|
-
require 'multi_json'
|
9
|
-
require 'benchmark'
|
10
|
-
require 'yajl'
|
11
|
-
require 'json'
|
12
|
-
require 'oj'
|
13
|
-
|
14
|
-
iter = 1_000_000
|
15
|
-
iter = 100_000
|
16
|
-
|
17
|
-
json = %({"k1":"val1","k2":"val2","k3":"val3"})
|
18
|
-
obj = { k1: "val1", k2: "val2", k3: "val3" }
|
19
|
-
|
20
|
-
puts "Benchmarks for different JSON handlers with MultiJson."
|
21
|
-
puts " Ruby #{RUBY_VERSION}"
|
22
|
-
puts " #{iter} iterations"
|
23
|
-
|
24
|
-
MultiJson.engine = :oj
|
25
|
-
dt = Benchmark.realtime { iter.times { MultiJson.decode(json) }}
|
26
|
-
et = Benchmark.realtime { iter.times { MultiJson.encode(obj) }}
|
27
|
-
puts " Oj decode: #{dt} encode: #{et}"
|
28
|
-
|
29
|
-
MultiJson.engine = :yajl
|
30
|
-
dt = Benchmark.realtime { iter.times { MultiJson.decode(json) }}
|
31
|
-
et = Benchmark.realtime { iter.times { MultiJson.encode(obj) }}
|
32
|
-
puts " Yajl decode: #{dt} encode: #{et}"
|
33
|
-
|
34
|
-
MultiJson.engine = :json_gem
|
35
|
-
dt = Benchmark.realtime { iter.times { MultiJson.decode(json) }}
|
36
|
-
et = Benchmark.realtime { iter.times { MultiJson.encode(obj) }}
|
37
|
-
puts " Json decode: #{dt} encode: #{et}"
|
38
|
-
|
39
|
-
Oj.default_options = { :mode => :compat, :time_format => :ruby }
|
40
|
-
dt = Benchmark.realtime { iter.times { Oj.load(json) }}
|
41
|
-
et = Benchmark.realtime { iter.times { Oj.dump(obj) }}
|
42
|
-
puts "Raw Oj decode: #{dt} encode: #{et}"
|
43
|
-
|
44
|
-
ye = Yajl::Encoder.new
|
45
|
-
dt = Benchmark.realtime { iter.times { Yajl::Parser.parse(json) }}
|
46
|
-
et = Benchmark.realtime { iter.times { Yajl::Encoder.encode(obj) }}
|
47
|
-
e2 = Benchmark.realtime { iter.times { ye.encode(obj) }}
|
48
|
-
puts "Raw Yajl decode: #{dt} encode: #{et}, encoder: #{e2}"
|
data/test/perf.rb
DELETED
@@ -1,107 +0,0 @@
|
|
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
|