ffi-yajl 2.3.0-universal-java → 2.3.1-universal-java
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.
- checksums.yaml +4 -4
- data/README.md +31 -73
- data/Rakefile +55 -96
- data/bin/ffi-yajl-bench +7 -7
- data/ext/ffi_yajl/ext/dlopen/extconf.rb +5 -5
- data/ext/ffi_yajl/ext/encoder/extconf.rb +12 -12
- data/ext/ffi_yajl/ext/parser/extconf.rb +12 -12
- data/lib/ffi_yajl.rb +7 -7
- data/lib/ffi_yajl/benchmark.rb +5 -5
- data/lib/ffi_yajl/benchmark/encode.rb +8 -8
- data/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb +9 -9
- data/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb +11 -11
- data/lib/ffi_yajl/benchmark/encode_profile.rb +5 -5
- data/lib/ffi_yajl/benchmark/http.rb +12 -12
- data/lib/ffi_yajl/benchmark/parse.rb +8 -8
- data/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb +10 -10
- data/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb +11 -11
- data/lib/ffi_yajl/benchmark/parse_profile.rb +5 -5
- data/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb +4 -4
- data/lib/ffi_yajl/benchmark/parse_stream.rb +9 -9
- data/lib/ffi_yajl/encoder.rb +2 -2
- data/lib/ffi_yajl/ext.rb +9 -9
- data/lib/ffi_yajl/ffi.rb +8 -8
- data/lib/ffi_yajl/ffi/encoder.rb +9 -27
- data/lib/ffi_yajl/ffi/parser.rb +5 -5
- data/lib/ffi_yajl/map_library_name.rb +3 -3
- data/lib/ffi_yajl/parser.rb +2 -2
- data/lib/ffi_yajl/version.rb +2 -2
- data/spec/ffi_yajl/encoder_spec.rb +10 -10
- data/spec/ffi_yajl/map_library_name_spec.rb +2 -2
- data/spec/ffi_yajl/parser_spec.rb +7 -7
- data/spec/spec_helper.rb +4 -4
- metadata +12 -26
@@ -1,9 +1,9 @@
|
|
1
1
|
# rubocop:disable Style/GlobalVars
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
2
|
+
require "mkmf"
|
3
|
+
require "rubygems"
|
4
|
+
require "libyajl2"
|
5
5
|
|
6
|
-
RbConfig::MAKEFILE_CONFIG[
|
6
|
+
RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
|
7
7
|
|
8
8
|
# pick up the vendored libyajl2 out of the libyajl2 gem
|
9
9
|
$CFLAGS = "-I#{Libyajl2.include_path} #{$CFLAGS}"
|
@@ -16,7 +16,7 @@ puts $CFLAGS
|
|
16
16
|
puts $LDFLAGS
|
17
17
|
|
18
18
|
# except if you're doing an unoptimized gcc install we're going to help you out a bit
|
19
|
-
if RbConfig::MAKEFILE_CONFIG[
|
19
|
+
if RbConfig::MAKEFILE_CONFIG["CC"] =~ /gcc|clang/
|
20
20
|
$CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
|
21
21
|
# how many people realize that -Wall is a compiler-specific flag???
|
22
22
|
# apparently not many based on reading lots of shitty extconf.rb's out there
|
@@ -34,32 +34,32 @@ end
|
|
34
34
|
|
35
35
|
# NOTE: find_library has the side effect of adding -lyajl to the flags which we are deliberately
|
36
36
|
# avoiding doing with the libyajl2-gem (allowing it to be lazily loaded with dlopen)
|
37
|
-
if !windows? && !find_header(
|
37
|
+
if !windows? && !find_header("yajl/yajl_tree.h")
|
38
38
|
puts "libyajl2 headers not found in libyajl2-gem, searching for system libraries..."
|
39
39
|
|
40
40
|
HEADER_DIRS = [
|
41
41
|
"/opt/local/include", # MacPorts
|
42
42
|
"/usr/local/include", # /usr/local
|
43
|
-
RbConfig::CONFIG[
|
43
|
+
RbConfig::CONFIG["includedir"], # Ruby
|
44
44
|
"/usr/include", # (default)
|
45
45
|
]
|
46
46
|
|
47
47
|
LIB_DIRS = [
|
48
48
|
"/opt/local/lib", # MacPorts
|
49
49
|
"/usr/local/lib", # /usr/local + Homebrew
|
50
|
-
RbConfig::CONFIG[
|
50
|
+
RbConfig::CONFIG["libdir"], # Ruby
|
51
51
|
"/usr/lib", # (default)
|
52
52
|
]
|
53
53
|
|
54
54
|
# add --with-yajl-dir, --with-yajl-include, --with-yajl-lib
|
55
|
-
dir_config(
|
55
|
+
dir_config("yajl", HEADER_DIRS, LIB_DIRS)
|
56
56
|
|
57
57
|
# here we use find_library in order to deliberately link with -lyajl as a useful side-effect
|
58
|
-
unless find_header(
|
58
|
+
unless find_header("yajl/yajl_tree.h") && find_library("yajl", "yajl_complete_parse")
|
59
59
|
abort "libyajl2 is missing. please install libyajl2"
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
dir_config
|
63
|
+
dir_config "parser"
|
64
64
|
|
65
|
-
create_makefile
|
65
|
+
create_makefile "ffi_yajl/ext/parser"
|
data/lib/ffi_yajl.rb
CHANGED
@@ -34,17 +34,17 @@
|
|
34
34
|
# dropped, so don't bother asking for that.
|
35
35
|
# - Then we try the c-ext and rescue into ffi that fails
|
36
36
|
#
|
37
|
-
if ENV[
|
38
|
-
require
|
39
|
-
elsif ENV[
|
40
|
-
require
|
37
|
+
if ENV["FORCE_FFI_YAJL"] == "ext"
|
38
|
+
require "ffi_yajl/ext"
|
39
|
+
elsif ENV["FORCE_FFI_YAJL"] == "ffi"
|
40
|
+
require "ffi_yajl/ffi"
|
41
41
|
elsif RUBY_PLATFORM == "java"
|
42
|
-
require
|
42
|
+
require "ffi_yajl/ffi"
|
43
43
|
else
|
44
44
|
begin
|
45
|
-
require
|
45
|
+
require "ffi_yajl/ext"
|
46
46
|
rescue LoadError
|
47
47
|
warn "failed to load the ffi-yajl c-extension, falling back to ffi interface"
|
48
|
-
require
|
48
|
+
require "ffi_yajl/ffi"
|
49
49
|
end
|
50
50
|
end
|
data/lib/ffi_yajl/benchmark.rb
CHANGED
@@ -20,8 +20,8 @@
|
|
20
20
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
23
|
+
require "ffi_yajl/benchmark/encode.rb"
|
24
|
+
require "ffi_yajl/benchmark/encode_profile.rb"
|
25
|
+
require "ffi_yajl/benchmark/parse.rb"
|
26
|
+
require "ffi_yajl/benchmark/parse_profile.rb"
|
27
|
+
require "ffi_yajl/benchmark/parse_profile_ruby_prof.rb"
|
@@ -1,26 +1,26 @@
|
|
1
1
|
# Portions Originally Copyright (c) 2008-2011 Brian Lopez - http://github.com/brianmario
|
2
2
|
# See MIT-LICENSE
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "stringio"
|
7
7
|
if !defined?(RUBY_ENGINE) || RUBY_ENGINE !~ /jruby/
|
8
8
|
begin
|
9
|
-
require
|
9
|
+
require "yajl"
|
10
10
|
rescue LoadError
|
11
11
|
puts "INFO: yajl-ruby not installed"
|
12
12
|
end
|
13
13
|
else
|
14
14
|
puts "INFO: skipping yajl-ruby on jruby"
|
15
15
|
end
|
16
|
-
require
|
16
|
+
require "ffi_yajl"
|
17
17
|
begin
|
18
|
-
require
|
18
|
+
require "json"
|
19
19
|
rescue LoadError
|
20
20
|
puts "INFO: json gem not installed"
|
21
21
|
end
|
22
22
|
begin
|
23
|
-
require
|
23
|
+
require "oj"
|
24
24
|
rescue LoadError
|
25
25
|
puts "INFO: oj gem not installed"
|
26
26
|
end
|
@@ -31,7 +31,7 @@ module FFI_Yajl
|
|
31
31
|
def run
|
32
32
|
# filename = ARGV[0] || 'benchmark/subjects/ohai.json'
|
33
33
|
filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json"))
|
34
|
-
hash = File.open(filename,
|
34
|
+
hash = File.open(filename, "rb") { |f| FFI_Yajl::Parser.parse(f.read) }
|
35
35
|
|
36
36
|
times = ARGV[1] ? ARGV[1].to_i : 1000
|
37
37
|
puts "Starting benchmark encoding #{filename} #{times} times\n\n"
|
@@ -1,18 +1,18 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "yajl"
|
7
|
+
require "stringio"
|
8
8
|
begin
|
9
|
-
require
|
9
|
+
require "json"
|
10
10
|
rescue LoadError
|
11
11
|
end
|
12
12
|
|
13
13
|
times = ARGV[0] ? ARGV[0].to_i : 1000
|
14
|
-
filename =
|
15
|
-
json = File.new(filename,
|
14
|
+
filename = "benchmark/subjects/ohai.json"
|
15
|
+
json = File.new(filename, "r")
|
16
16
|
hash = Yajl::Parser.new.parse(json)
|
17
17
|
json.close
|
18
18
|
|
@@ -1,18 +1,18 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "yajl"
|
7
7
|
begin
|
8
|
-
require
|
8
|
+
require "json"
|
9
9
|
rescue LoadError
|
10
10
|
end
|
11
|
-
require
|
11
|
+
require "yaml"
|
12
12
|
|
13
13
|
# JSON Section
|
14
|
-
filename =
|
15
|
-
json = File.new(filename,
|
14
|
+
filename = "benchmark/subjects/ohai.json"
|
15
|
+
json = File.new(filename, "r")
|
16
16
|
hash = Yajl::Parser.new.parse(json)
|
17
17
|
json.close
|
18
18
|
|
@@ -33,8 +33,8 @@ Benchmark.bmbm do |x|
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# YAML Section
|
36
|
-
filename =
|
37
|
-
yml = File.new(filename,
|
36
|
+
filename = "benchmark/subjects/ohai.yml"
|
37
|
+
yml = File.new(filename, "r")
|
38
38
|
data = YAML.load_stream(yml)
|
39
39
|
yml.close
|
40
40
|
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# Portions Originally Copyright (c) 2008-2011 Brian Lopez - http://github.com/brianmario
|
2
2
|
# See MIT-LICENSE
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "ffi_yajl"
|
6
6
|
begin
|
7
|
-
require
|
7
|
+
require "perftools"
|
8
8
|
rescue LoadError
|
9
9
|
puts "INFO: perftools.rb gem not installed"
|
10
10
|
end
|
11
11
|
|
12
|
-
ENV[
|
12
|
+
ENV["CPUPROFILE_FREQUENCY"] = "4000"
|
13
13
|
|
14
14
|
module FFI_Yajl
|
15
15
|
class Benchmark
|
@@ -18,7 +18,7 @@ module FFI_Yajl
|
|
18
18
|
return unless defined?(PerfTools)
|
19
19
|
|
20
20
|
filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json"))
|
21
|
-
hash = File.open(filename,
|
21
|
+
hash = File.open(filename, "rb") { |f| FFI_Yajl::Parser.parse(f.read) }
|
22
22
|
|
23
23
|
times = 1000
|
24
24
|
puts "Starting profiling encoding #{filename} #{times} times\n\n"
|
@@ -1,17 +1,17 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "yajl/http_stream"
|
7
|
+
require "yajl/gzip"
|
8
|
+
require "yajl/deflate"
|
9
|
+
require "yajl/bzip2" unless defined?(Bzip2)
|
10
|
+
require "json"
|
11
|
+
require "uri"
|
12
|
+
require "net/http"
|
13
13
|
|
14
|
-
uri = URI.parse(
|
14
|
+
uri = URI.parse("http://search.twitter.com/search.json?q=github")
|
15
15
|
# uri = URI.parse('http://localhost/yajl-ruby.git/benchmark/subjects/contacts.json')
|
16
16
|
|
17
17
|
times = ARGV[0] ? ARGV[0].to_i : 1
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "rubygems"
|
2
|
+
require "benchmark"
|
3
|
+
require "yajl"
|
4
|
+
require "ffi_yajl"
|
5
5
|
if !defined?(RUBY_ENGINE) || RUBY_ENGINE !~ /jruby/
|
6
6
|
begin
|
7
|
-
require
|
7
|
+
require "yajl"
|
8
8
|
rescue LoadError
|
9
9
|
puts "INFO: yajl-ruby not installed"
|
10
10
|
end
|
@@ -12,11 +12,11 @@ else
|
|
12
12
|
puts "INFO: skipping yajl-ruby on jruby"
|
13
13
|
end
|
14
14
|
begin
|
15
|
-
require
|
15
|
+
require "json"
|
16
16
|
rescue LoadError
|
17
17
|
end
|
18
18
|
begin
|
19
|
-
require
|
19
|
+
require "oj"
|
20
20
|
rescue LoadError
|
21
21
|
end
|
22
22
|
|
@@ -25,7 +25,7 @@ module FFI_Yajl
|
|
25
25
|
class Parse
|
26
26
|
def run
|
27
27
|
filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "item.json"))
|
28
|
-
json = File.new(filename,
|
28
|
+
json = File.new(filename, "r")
|
29
29
|
json_str = json.read
|
30
30
|
|
31
31
|
times = ARGV[1] ? ARGV[1].to_i : 10_000
|
@@ -1,19 +1,19 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "yajl"
|
7
7
|
begin
|
8
|
-
require
|
8
|
+
require "json"
|
9
9
|
rescue LoadError
|
10
10
|
end
|
11
11
|
|
12
12
|
# JSON section
|
13
|
-
filename =
|
14
|
-
marshal_filename =
|
15
|
-
json = File.new(filename,
|
16
|
-
marshal_file = File.new(marshal_filename,
|
13
|
+
filename = "benchmark/subjects/ohai.json"
|
14
|
+
marshal_filename = "benchmark/subjects/ohai.marshal_dump"
|
15
|
+
json = File.new(filename, "r")
|
16
|
+
marshal_file = File.new(marshal_filename, "r")
|
17
17
|
|
18
18
|
hash = {}
|
19
19
|
|
@@ -1,18 +1,18 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "yajl"
|
7
7
|
begin
|
8
|
-
require
|
8
|
+
require "json"
|
9
9
|
rescue LoadError
|
10
10
|
end
|
11
|
-
require
|
11
|
+
require "yaml"
|
12
12
|
|
13
13
|
# JSON section
|
14
|
-
filename =
|
15
|
-
json = File.new(filename,
|
14
|
+
filename = "benchmark/subjects/ohai.json"
|
15
|
+
json = File.new(filename, "r")
|
16
16
|
|
17
17
|
times = ARGV[0] ? ARGV[0].to_i : 1000
|
18
18
|
puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n"
|
@@ -39,8 +39,8 @@ end
|
|
39
39
|
json.close
|
40
40
|
|
41
41
|
# YAML section
|
42
|
-
filename =
|
43
|
-
yaml = File.new(filename,
|
42
|
+
filename = "benchmark/subjects/ohai.yml"
|
43
|
+
yaml = File.new(filename, "r")
|
44
44
|
|
45
45
|
puts "Starting benchmark parsing #{File.size(filename)} bytes of YAML data #{times} times\n\n"
|
46
46
|
Benchmark.bmbm do |x|
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# Portions Originally Copyright (c) 2008-2011 Brian Lopez - http://github.com/brianmario
|
2
2
|
# See MIT-LICENSE
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "ffi_yajl"
|
6
6
|
begin
|
7
|
-
require
|
7
|
+
require "perftools"
|
8
8
|
rescue LoadError
|
9
9
|
puts "INFO: perftools.rb gem not installed"
|
10
10
|
end
|
11
11
|
|
12
|
-
ENV[
|
12
|
+
ENV["CPUPROFILE_FREQUENCY"] = "4000"
|
13
13
|
|
14
14
|
module FFI_Yajl
|
15
15
|
class Benchmark
|
@@ -18,7 +18,7 @@ module FFI_Yajl
|
|
18
18
|
return if defined?(PerfTools)
|
19
19
|
|
20
20
|
filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json"))
|
21
|
-
json = File.new(filename,
|
21
|
+
json = File.new(filename, "r").read
|
22
22
|
|
23
23
|
times = 1000
|
24
24
|
puts "Starting profiling encoding #{filename} #{times} times\n\n"
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# Portions Originally Copyright (c) 2008-2011 Brian Lopez - http://github.com/brianmario
|
2
2
|
# See MIT-LICENSE
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "ffi_yajl"
|
6
6
|
|
7
7
|
module FFI_Yajl
|
8
8
|
class Benchmark
|
9
9
|
class ParseProfileRubyProf
|
10
10
|
def run
|
11
11
|
begin
|
12
|
-
require
|
12
|
+
require "ruby-prof"
|
13
13
|
rescue LoadError
|
14
14
|
puts "INFO: perftools.rb gem not installed"
|
15
15
|
end
|
@@ -17,7 +17,7 @@ module FFI_Yajl
|
|
17
17
|
return if defined?(RubyProf)
|
18
18
|
|
19
19
|
filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json"))
|
20
|
-
json = File.new(filename,
|
20
|
+
json = File.new(filename, "r").read
|
21
21
|
|
22
22
|
times = 1000
|
23
23
|
puts "Starting profiling encoding #{filename} #{times} times\n\n"
|
@@ -1,20 +1,20 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require "rubygems"
|
5
|
+
require "benchmark"
|
6
|
+
require "yajl"
|
7
7
|
begin
|
8
|
-
require
|
8
|
+
require "json"
|
9
9
|
rescue LoadError
|
10
10
|
end
|
11
11
|
begin
|
12
|
-
require
|
12
|
+
require "active_support"
|
13
13
|
rescue LoadError
|
14
14
|
end
|
15
15
|
|
16
|
-
filename =
|
17
|
-
json = File.new(filename,
|
16
|
+
filename = "benchmark/subjects/twitter_stream.json"
|
17
|
+
json = File.new(filename, "r")
|
18
18
|
|
19
19
|
times = ARGV[0] ? ARGV[0].to_i : 100
|
20
20
|
puts "Starting benchmark parsing JSON stream (#{File.size(filename)} bytes of JSON data with 430 JSON separate strings) #{times} times\n\n"
|