diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2015-07-10 13:35:58 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2015-07-10 13:35:58 -0700 |
commit | 1050b6b86870acb3b3dd288fcc27ee44fdf88458 (patch) | |
tree | e8ad9a4f32b116f9d2c6c6bb925b5a53e11750d7 | |
parent | d6e5fa74de5b13abc6c60a95b83acc8eb8d3ed05 (diff) | |
parent | 1a7a0264c7734dfca9c29e11a039198cb6bd9840 (diff) | |
download | ffi-yajl-1050b6b86870acb3b3dd288fcc27ee44fdf88458.tar.gz |
Merge pull request #68 from chef/lcg/more-cops
Lcg/more cops
-rw-r--r-- | .rubocop.yml | 11 | ||||
-rw-r--r-- | Gemfile | 4 | ||||
-rw-r--r-- | Rakefile | 12 | ||||
-rw-r--r-- | ext/ffi_yajl/ext/dlopen/extconf.rb | 1 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/encode.rb | 117 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/encode_json_and_marshal.rb | 28 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/encode_json_and_yaml.rb | 32 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/encode_profile.rb | 24 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/http.rb | 20 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/parse.rb | 192 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/parse_json_and_marshal.rb | 32 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/parse_json_and_yaml.rb | 36 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/parse_profile.rb | 22 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb | 25 | ||||
-rw-r--r-- | lib/ffi_yajl/benchmark/parse_stream.rb | 32 | ||||
-rw-r--r-- | lib/ffi_yajl/encoder.rb | 4 | ||||
-rw-r--r-- | lib/ffi_yajl/ffi/encoder.rb | 10 | ||||
-rw-r--r-- | lib/ffi_yajl/ffi/parser.rb | 14 | ||||
-rw-r--r-- | spec/ffi_yajl/encoder_spec.rb | 8 | ||||
-rw-r--r-- | spec/ffi_yajl/parser_spec.rb | 48 | ||||
-rw-r--r-- | spec/spec_helper.rb | 14 |
21 files changed, 287 insertions, 399 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 170fc40..e843ff7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,8 @@ AbcSize: Enabled: false AndOr: Enabled: false +Lint/AssignmentInCondition: + Enabled: false ClassAndModuleCamelCase: Enabled: false ClassLength: @@ -18,9 +20,14 @@ Encoding: Enabled: false Eval: Enabled: false +Style/FileName: + Exclude: + - bin/ffi-yajl-bench FormatString: Enabled: false -HashSyntax: +Style/GuardClause: + Enabled: false +Lint/HandleExceptions: Enabled: false LineLength: Enabled: false @@ -40,6 +47,8 @@ PercentLiteralDelimiters: '%x': '{}' RegexpLiteral: Enabled: false +Style/Semicolon: + Enabled: false SignalException: Enabled: false SingleSpaceBeforeFirstArg: @@ -1,6 +1,6 @@ source "https://rubygems.org" -gemspec :name => "ffi-yajl" +gemspec name: "ffi-yajl" platforms :rbx do gem 'rubysl', '~> 2.0' @@ -8,7 +8,7 @@ end group :development do # for testing loading concurrently with yajl-ruby, not on jruby - gem 'yajl-ruby', :platforms => [ :ruby, :mswin, :mingw ] + gem 'yajl-ruby', platforms: [ :ruby, :mswin, :mingw ] end group :development_extras do @@ -11,7 +11,7 @@ Dir[File.expand_path("../*gemspec", __FILE__)].reverse_each do |gemspec_path| end desc "Build it and ship it" -task :ship => [:clean, :gem] do +task ship: [:clean, :gem] do sh("git tag #{FFI_Yajl::VERSION}") sh("git push --tags") Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse_each do |built_gem| @@ -27,7 +27,7 @@ task :clean do end desc "install the gem locally" -task :install => [:package] do +task install: [:package] do if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby" sh %{gem install pkg/#{unix_gemspec.name}-#{unix_gemspec.version}-universal-java.gem} else @@ -162,12 +162,12 @@ else end desc 'Run all style checks' -task :style => ['style:rubocop', 'style:reek'] +task style: ['style:rubocop', 'style:reek'] desc 'Run style + spec tests by default on travis' -task :travis => %w{style spec} +task travis: %w{style spec} desc 'Run style, spec and test kichen on travis' -task :travis_all => ['style', 'spec', 'integration:cloud'] +task travis_all: ['style', 'spec', 'integration:cloud'] -task :default => ['style', 'spec', 'integration:vagrant'] +task default: ['style', 'spec', 'integration:vagrant'] diff --git a/ext/ffi_yajl/ext/dlopen/extconf.rb b/ext/ffi_yajl/ext/dlopen/extconf.rb index 7e18469..f35d0cb 100644 --- a/ext/ffi_yajl/ext/dlopen/extconf.rb +++ b/ext/ffi_yajl/ext/dlopen/extconf.rb @@ -1,3 +1,4 @@ +# rubocop:disable Style/GlobalVars require 'mkmf' require 'rubygems' diff --git a/lib/ffi_yajl/benchmark/encode.rb b/lib/ffi_yajl/benchmark/encode.rb index eda4fe7..fc03c06 100644 --- a/lib/ffi_yajl/benchmark/encode.rb +++ b/lib/ffi_yajl/benchmark/encode.rb @@ -5,14 +5,10 @@ require 'rubygems' require 'benchmark' require 'stringio' if !defined?(RUBY_ENGINE) || RUBY_ENGINE !~ /jruby/ - if ENV['FORCE_FFI_YAJL'] != 'ext' - begin - require 'yajl' - rescue Exception - puts "INFO: yajl-ruby not installed" - end - else - puts "INFO: skipping yajl-ruby because we're using the C extension" + begin + require 'yajl' + rescue LoadError + puts "INFO: yajl-ruby not installed" end else puts "INFO: skipping yajl-ruby on jruby" @@ -20,22 +16,12 @@ end require 'ffi_yajl' begin require 'json' -rescue Exception +rescue LoadError puts "INFO: json gem not installed" end begin - require 'psych' -rescue Exception - puts "INFO: psych gem not installed" -end -begin - require 'active_support' -rescue Exception - puts "INFO: active_support gem not installed" -end -begin require 'oj' -rescue Exception +rescue LoadError puts "INFO: oj gem not installed" end @@ -49,88 +35,47 @@ module FFI_Yajl times = ARGV[1] ? ARGV[1].to_i : 1000 puts "Starting benchmark encoding #{filename} #{times} times\n\n" - ::Benchmark.bmbm { |x| - x.report("FFI_Yajl::Encoder.encode (to a String)") { - times.times { - output = FFI_Yajl::Encoder.encode(hash) - } - } + ::Benchmark.bmbm do |x| + x.report("FFI_Yajl::Encoder.encode (to a String)") do + times.times { FFI_Yajl::Encoder.encode(hash) } + end ffi_string_encoder = FFI_Yajl::Encoder.new - x.report("FFI_Yajl::Encoder#encode (to a String)") { - times.times { - output = ffi_string_encoder.encode(hash) - } - } + x.report("FFI_Yajl::Encoder#encode (to a String)") do + times.times { ffi_string_encoder.encode(hash) } + end if defined?(Oj) - x.report("Oj.dump (to a String)") { - times.times { - output = Oj.dump(hash) - } - } + x.report("Oj.dump (to a String)") do + times.times { Oj.dump(hash) } + end end if defined?(Yajl::Encoder) - x.report("Yajl::Encoder.encode (to a String)") { - times.times { - output = Yajl::Encoder.encode(hash) - } - } + x.report("Yajl::Encoder.encode (to a String)") do + times.times { Yajl::Encoder.encode(hash) } + end io_encoder = Yajl::Encoder.new - x.report("Yajl::Encoder#encode (to an IO)") { - times.times { - io_encoder.encode(hash, StringIO.new) - } - } + x.report("Yajl::Encoder#encode (to an IO)") do + times.times { io_encoder.encode(hash, StringIO.new) } + end string_encoder = Yajl::Encoder.new - x.report("Yajl::Encoder#encode (to a String)") { - times.times { - output = string_encoder.encode(hash) - } - } + x.report("Yajl::Encoder#encode (to a String)") do + times.times { string_encoder.encode(hash) } + end end if defined?(JSON) - x.report("JSON.generate") { - times.times { - JSON.generate(hash) - } - } - x.report("JSON.fast_generate") { - times.times { - JSON.fast_generate(hash) - } - } - end - if defined?(Psych) - x.report("Psych.to_json") { - times.times { - Psych.to_json(hash) - } - } - if defined?(Psych::JSON::Stream) - x.report("Psych::JSON::Stream") { - times.times { - io = StringIO.new - stream = Psych::JSON::Stream.new io - stream.start - stream.push hash - stream.finish - } - } + x.report("JSON.generate") do + times.times { JSON.generate(hash) } + end + x.report("JSON.fast_generate") do + times.times { JSON.fast_generate(hash) } end end - # if defined?(ActiveSupport::JSON) - # x.report("ActiveSupport::JSON.encode") { - # times.times { - # ActiveSupport::JSON.encode(hash) - # } - # } - # end - } + end end end end diff --git a/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb b/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb index 73a7d0c..e9d19bc 100644 --- a/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb +++ b/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb @@ -17,26 +17,26 @@ hash = Yajl::Parser.new.parse(json) json.close puts "Starting benchmark encoding #{filename} #{times} times\n\n" -Benchmark.bmbm { |x| +Benchmark.bmbm do |x| encoder = Yajl::Encoder.new - x.report { + x.report do puts "Yajl::Encoder#encode" - times.times { + times.times do encoder.encode(hash, StringIO.new) - } - } + end + end if defined?(JSON) - x.report { + x.report do puts "JSON's #to_json" - times.times { + times.times do JSON.generate(hash) - } - } + end + end end - x.report { + x.report do puts "Marshal.dump" - times.times { + times.times do Marshal.dump(hash) - } - } -} + end + end +end diff --git a/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb b/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb index 4ceb022..33dbbb2 100644 --- a/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb +++ b/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb @@ -18,23 +18,19 @@ json.close times = ARGV[0] ? ARGV[0].to_i : 1000 puts "Starting benchmark encoding #{filename} into JSON #{times} times\n\n" -Benchmark.bmbm { |x| +Benchmark.bmbm do |x| encoder = Yajl::Encoder.new - x.report { + x.report do puts "Yajl::Encoder#encode" - times.times { - encoder.encode(hash, StringIO.new) - } - } + times.times { encoder.encode(hash, StringIO.new) } + end if defined?(JSON) - x.report { + x.report do puts "JSON's #to_json" - times.times { - JSON.generate(hash) - } - } + times.times { JSON.generate(hash) } + end end -} +end # YAML Section filename = 'benchmark/subjects/ohai.yml' @@ -43,11 +39,9 @@ data = YAML.load_stream(yml) yml.close puts "Starting benchmark encoding #{filename} into YAML #{times} times\n\n" -Benchmark.bmbm { |x| - x.report { +Benchmark.bmbm do |x| + x.report do puts "YAML.dump" - times.times { - YAML.dump(data, StringIO.new) - } - } -} + times.times { YAML.dump(data, StringIO.new) } + end +end diff --git a/lib/ffi_yajl/benchmark/encode_profile.rb b/lib/ffi_yajl/benchmark/encode_profile.rb index f7ac7c2..36b92c7 100644 --- a/lib/ffi_yajl/benchmark/encode_profile.rb +++ b/lib/ffi_yajl/benchmark/encode_profile.rb @@ -5,7 +5,7 @@ require 'rubygems' require 'ffi_yajl' begin require 'perftools' -rescue Exception +rescue LoadError puts "INFO: perftools.rb gem not installed" end @@ -15,21 +15,19 @@ module FFI_Yajl class Benchmark class EncodeProfile def run - if defined?(PerfTools) - filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json")) - hash = File.open(filename, 'rb') { |f| FFI_Yajl::Parser.parse(f.read) } + return unless defined?(PerfTools) - times = 1000 - puts "Starting profiling encoding #{filename} #{times} times\n\n" + filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json")) + hash = File.open(filename, 'rb') { |f| FFI_Yajl::Parser.parse(f.read) } - ffi_string_encoder = FFI_Yajl::Encoder.new - PerfTools::CpuProfiler.start("/tmp/ffi_yajl_encode_profile.out") do - times.times { - output = ffi_string_encoder.encode(hash) - } - end - system("pprof.rb --text /tmp/ffi_yajl_encode_profile.out") + times = 1000 + puts "Starting profiling encoding #{filename} #{times} times\n\n" + + ffi_string_encoder = FFI_Yajl::Encoder.new + PerfTools::CpuProfiler.start("/tmp/ffi_yajl_encode_profile.out") do + times.times { ffi_string_encoder.encode(hash) } end + system("pprof.rb --text /tmp/ffi_yajl_encode_profile.out") end end end diff --git a/lib/ffi_yajl/benchmark/http.rb b/lib/ffi_yajl/benchmark/http.rb index 4c61df5..b94a46c 100644 --- a/lib/ffi_yajl/benchmark/http.rb +++ b/lib/ffi_yajl/benchmark/http.rb @@ -16,17 +16,13 @@ uri = URI.parse('http://search.twitter.com/search.json?q=github') times = ARGV[0] ? ARGV[0].to_i : 1 puts "Starting benchmark parsing #{uri} #{times} times\n\n" -Benchmark.bmbm { |x| - x.report { +Benchmark.bmbm do |x| + x.report do puts "Yajl::HttpStream.get" - times.times { - Yajl::HttpStream.get(uri) - } - } - x.report { + times.times { Yajl::HttpStream.get(uri) } + end + x.report do puts "JSON.parser" - times.times { - JSON.parse(Net::HTTP.get_response(uri).body, :max_nesting => false) - } - } -} + times.times { JSON.parse(Net::HTTP.get_response(uri).body, max_nesting: false) } + end +end diff --git a/lib/ffi_yajl/benchmark/parse.rb b/lib/ffi_yajl/benchmark/parse.rb index 7e1f3a6..6aacc94 100644 --- a/lib/ffi_yajl/benchmark/parse.rb +++ b/lib/ffi_yajl/benchmark/parse.rb @@ -1,17 +1,12 @@ require 'rubygems' require 'benchmark' -require 'yaml' require 'yajl' require 'ffi_yajl' if !defined?(RUBY_ENGINE) || RUBY_ENGINE !~ /jruby/ - if ENV['FORCE_FFI_YAJL'] != 'ext' - begin - require 'yajl' - rescue Exception - puts "INFO: yajl-ruby not installed" - end - else - puts "INFO: skipping yajl-ruby because we're using the C extension" + begin + require 'yajl' + rescue LoadError + puts "INFO: yajl-ruby not installed" end else puts "INFO: skipping yajl-ruby on jruby" @@ -21,123 +16,78 @@ begin rescue LoadError end begin - require 'psych' -rescue LoadError -end -begin - require 'active_support' -rescue LoadError -end -begin require 'oj' rescue LoadError end -class FFI_Yajl::Benchmark::Parse - def run - filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "item.json")) - json = File.new(filename, 'r') - json_str = json.read +module FFI_Yajl + class Benchmark + class Parse + def run + filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "item.json")) + json = File.new(filename, 'r') + json_str = json.read - times = ARGV[1] ? ARGV[1].to_i : 10_000 - puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n" - Benchmark.bmbm { |x| - x.report { - puts "FFI_Yajl::Parser.parse (from a String)" - times.times { - FFI_Yajl::Parser.parse(json_str) - } - } - # ffi_parser = FFI_Yajl::Parser.new - # x.report { - # puts "FFI_Yajl::Parser#parse (from a String)" - # times.times { - # json.rewind - # ffi_parser.parse(json.read) - # } - # } - if defined?(Yajl::Parser) - x.report { - puts "Yajl::Parser.parse (from a String)" - times.times { - Yajl::Parser.parse(json_str) - } - } - io_parser = Yajl::Parser.new - io_parser.on_parse_complete = lambda { |obj| } if times > 1 - x.report { - puts "Yajl::Parser#parse (from an IO)" - times.times { - json.rewind - io_parser.parse(json) - } - } - string_parser = Yajl::Parser.new - string_parser.on_parse_complete = lambda { |obj| } if times > 1 - x.report { - puts "Yajl::Parser#parse (from a String)" - times.times { - json.rewind - string_parser.parse(json_str) - } - } - end - if defined?(Oj) - x.report { - puts "Oj.load" - times.times { - json.rewind - Oj.load(json.read) - } - } - end - if defined?(JSON) - x.report { - puts "JSON.parse" - times.times { - json.rewind - JSON.parse(json.read, :max_nesting => false) - } - } + times = ARGV[1] ? ARGV[1].to_i : 10_000 + puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n" + ::Benchmark.bmbm do |x| + x.report do + puts "FFI_Yajl::Parser.parse (from a String)" + times.times { FFI_Yajl::Parser.parse(json_str) } + end + # ffi_parser = FFI_Yajl::Parser.new + # x.report { + # puts "FFI_Yajl::Parser#parse (from a String)" + # times.times { + # json.rewind + # ffi_parser.parse(json.read) + # } + # } + if defined?(Yajl::Parser) + x.report do + puts "Yajl::Parser.parse (from a String)" + times.times { Yajl::Parser.parse(json_str) } + end + io_parser = Yajl::Parser.new + io_parser.on_parse_complete = ->(obj) {} if times > 1 + x.report do + puts "Yajl::Parser#parse (from an IO)" + times.times do + json.rewind + io_parser.parse(json) + end + end + string_parser = Yajl::Parser.new + string_parser.on_parse_complete = ->(obj) {} if times > 1 + x.report do + puts "Yajl::Parser#parse (from a String)" + times.times do + json.rewind + string_parser.parse(json_str) + end + end + end + if defined?(Oj) + x.report do + puts "Oj.load" + times.times do + json.rewind + Oj.load(json.read) + end + end + end + if defined?(JSON) + x.report do + puts "JSON.parse" + times.times do + json.rewind + JSON.parse(json.read, max_nesting: false) + end + end + end + end + json.close end - if defined?(ActiveSupport::JSON) - x.report { - puts "ActiveSupport::JSON.decode" - times.times { - json.rewind - ActiveSupport::JSON.decode(json.read) - } - } - end - x.report { - puts "YAML.load (from an IO)" - times.times { - json.rewind - YAML.load(json) - } - } - x.report { - puts "YAML.load (from a String)" - times.times { - YAML.load(json_str) - } - } - if defined?(Psych) - x.report { - puts "Psych.load (from an IO)" - times.times { - json.rewind - Psych.load(json) - } - } - x.report { - puts "Psych.load (from a String)" - times.times { - Psych.load(json_str) - } - } - end - } - json.close + end end end diff --git a/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb b/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb index 163f559..cd07d46 100644 --- a/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb +++ b/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb @@ -19,32 +19,32 @@ hash = {} times = ARGV[0] ? ARGV[0].to_i : 1000 puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n" -Benchmark.bmbm { |x| - x.report { +Benchmark.bmbm do |x| + x.report do puts "Yajl::Parser#parse" yajl = Yajl::Parser.new - yajl.on_parse_complete = lambda { |obj| } if times > 1 - times.times { + yajl.on_parse_complete = ->(obj) {} if times > 1 + times.times do json.rewind hash = yajl.parse(json) - } - } + end + end if defined?(JSON) - x.report { + x.report do puts "JSON.parse" - times.times { + times.times do json.rewind - JSON.parse(json.read, :max_nesting => false) - } - } + JSON.parse(json.read, max_nesting: false) + end + end end - x.report { + x.report do puts "Marshal.load" - times.times { + times.times do marshal_file.rewind Marshal.load(marshal_file) - } - } -} + end + end +end json.close marshal_file.close diff --git a/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb b/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb index 4e96e02..6e479ce 100644 --- a/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb +++ b/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb @@ -16,26 +16,26 @@ json = File.new(filename, 'r') times = ARGV[0] ? ARGV[0].to_i : 1000 puts "Starting benchmark parsing #{File.size(filename)} bytes of JSON data #{times} times\n\n" -Benchmark.bmbm { |x| +Benchmark.bmbm do |x| parser = Yajl::Parser.new - parser.on_parse_complete = lambda { |obj| } if times > 1 - x.report { + parser.on_parse_complete = ->(obj) {} if times > 1 + x.report do puts "Yajl::Parser#parse" - times.times { + times.times do json.rewind parser.parse(json) - } - } + end + end if defined?(JSON) - x.report { + x.report do puts "JSON.parse" - times.times { + times.times do json.rewind - JSON.parse(json.read, :max_nesting => false) - } - } + JSON.parse(json.read, max_nesting: false) + end + end end -} +end json.close # YAML section @@ -43,13 +43,13 @@ filename = 'benchmark/subjects/ohai.yml' yaml = File.new(filename, 'r') puts "Starting benchmark parsing #{File.size(filename)} bytes of YAML data #{times} times\n\n" -Benchmark.bmbm { |x| - x.report { +Benchmark.bmbm do |x| + x.report do puts "YAML.load_stream" - times.times { + times.times do yaml.rewind YAML.load(yaml) - } - } -} + end + end +end yaml.close diff --git a/lib/ffi_yajl/benchmark/parse_profile.rb b/lib/ffi_yajl/benchmark/parse_profile.rb index 39343bc..6ef00ac 100644 --- a/lib/ffi_yajl/benchmark/parse_profile.rb +++ b/lib/ffi_yajl/benchmark/parse_profile.rb @@ -5,7 +5,7 @@ require 'rubygems' require 'ffi_yajl' begin require 'perftools' -rescue Exception +rescue LoadError puts "INFO: perftools.rb gem not installed" end @@ -15,20 +15,18 @@ module FFI_Yajl class Benchmark class ParseProfile def run - if defined?(PerfTools) - filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json")) - json = File.new(filename, 'r').read + return if defined?(PerfTools) - times = 1000 - puts "Starting profiling encoding #{filename} #{times} times\n\n" + filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json")) + json = File.new(filename, 'r').read - PerfTools::CpuProfiler.start("/tmp/ffi_yajl_encode_profile.out") do - times.times { - output = FFI_Yajl::Parser.parse(json) - } - end - system("pprof.rb --text /tmp/ffi_yajl_encode_profile.out") + times = 1000 + puts "Starting profiling encoding #{filename} #{times} times\n\n" + + PerfTools::CpuProfiler.start("/tmp/ffi_yajl_encode_profile.out") do + times.times { FFI_Yajl::Parser.parse(json) } end + system("pprof.rb --text /tmp/ffi_yajl_encode_profile.out") end end end diff --git a/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb b/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb index 8d9dd5d..51696c5 100644 --- a/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb +++ b/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb @@ -10,27 +10,24 @@ module FFI_Yajl def run begin require 'ruby-prof' - rescue Exception + rescue LoadError puts "INFO: perftools.rb gem not installed" end - if defined?(RubyProf) - filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json")) - json = File.new(filename, 'r').read + return if defined?(RubyProf) - times = 1000 - puts "Starting profiling encoding #{filename} #{times} times\n\n" + filename = File.expand_path(File.join(File.dirname(__FILE__), "subjects", "ohai.json")) + json = File.new(filename, 'r').read - result = RubyProf.profile do - times.times { - output = FFI_Yajl::Parser.parse(json) - } - end - - printer = RubyProf::GraphPrinter.new(result) - printer.print(STDOUT, {}) + times = 1000 + puts "Starting profiling encoding #{filename} #{times} times\n\n" + result = RubyProf.profile do + times.times { FFI_Yajl::Parser.parse(json) } end + + printer = RubyProf::GraphPrinter.new(result) + printer.print(STDOUT, {}) end end end diff --git a/lib/ffi_yajl/benchmark/parse_stream.rb b/lib/ffi_yajl/benchmark/parse_stream.rb index 955f22f..679eb92 100644 --- a/lib/ffi_yajl/benchmark/parse_stream.rb +++ b/lib/ffi_yajl/benchmark/parse_stream.rb @@ -18,37 +18,37 @@ json = File.new(filename, 'r') times = ARGV[0] ? ARGV[0].to_i : 100 puts "Starting benchmark parsing JSON stream (#{File.size(filename)} bytes of JSON data with 430 JSON separate strings) #{times} times\n\n" -Benchmark.bmbm { |x| +Benchmark.bmbm do |x| parser = Yajl::Parser.new - parser.on_parse_complete = lambda { |obj| } - x.report { + parser.on_parse_complete = ->(obj) {} + x.report do puts "Yajl::Parser#parse" - times.times { + times.times do json.rewind parser.parse(json) - } - } + end + end if defined?(JSON) - x.report { + x.report do puts "JSON.parse" - times.times { + times.times do json.rewind while chunk = json.gets - JSON.parse(chunk, :max_nesting => false) + JSON.parse(chunk, max_nesting: false) end - } - } + end + end end if defined?(ActiveSupport::JSON) - x.report { + x.report do puts "ActiveSupport::JSON.decode" - times.times { + times.times do json.rewind while chunk = json.gets ActiveSupport::JSON.decode(chunk) end - } - } + end + end end -} +end json.close diff --git a/lib/ffi_yajl/encoder.rb b/lib/ffi_yajl/encoder.rb index 9f2e564..f4dd8c8 100644 --- a/lib/ffi_yajl/encoder.rb +++ b/lib/ffi_yajl/encoder.rb @@ -41,7 +41,7 @@ module FFI_Yajl # call either the ext or ffi hook str = do_yajl_encode(obj, yajl_gen_opts, opts) # we can skip cleaning the whole string for utf-8 issues if we have yajl validate as we go - str.encode!("utf-8", "binary", :undef => :replace) unless yajl_gen_opts[:yajl_gen_validate_utf8] + str.encode!("utf-8", "binary", undef: :replace) unless yajl_gen_opts[:yajl_gen_validate_utf8] str end @@ -56,7 +56,7 @@ module FFI_Yajl def self.raise_error_for_status(status, token = nil) # scrub token to valid utf-8 since we may be issuing an exception on an invalid utf-8 token - token = token.to_s.encode("utf-8", "binary", :undef => :replace) + token = token.to_s.encode("utf-8", "binary", undef: :replace) case status when 1 # yajl_gen_keys_must_be_strings raise FFI_Yajl::EncodeError, "YAJL internal error: attempted use of non-string object as key" diff --git a/lib/ffi_yajl/ffi/encoder.rb b/lib/ffi_yajl/ffi/encoder.rb index 250ed68..304c85f 100644 --- a/lib/ffi_yajl/ffi/encoder.rb +++ b/lib/ffi_yajl/ffi/encoder.rb @@ -41,8 +41,8 @@ module FFI_Yajl # setup our own state state = { - :json_opts => opts, - :processing_key => false, + json_opts: opts, + processing_key: false, } # do the encoding @@ -159,7 +159,7 @@ class Fixnum def ffi_yajl(yajl_gen, state) str = to_s if str == "NaN" || str == "Infinity" || str == "-Infinity" - raise ::FFI_Yajl::EncodeError.new("'#{str}' is an invalid number") + raise ::FFI_Yajl::EncodeError, "'#{str}' is an invalid number" end if state[:processing_key] if ( status = FFI_Yajl.yajl_gen_string(yajl_gen, str, str.bytesize) ) != 0 @@ -177,7 +177,7 @@ class Bignum def ffi_yajl(yajl_gen, state) str = to_s if str == "NaN" || str == "Infinity" || str == "-Infinity" - raise ::FFI_Yajl::EncodeError.new("'#{str}' is an invalid number") + raise ::FFI_Yajl::EncodeError, "'#{str}' is an invalid number" end if state[:processing_key] if ( status = FFI_Yajl.yajl_gen_string(yajl_gen, str, str.bytesize) ) != 0 @@ -195,7 +195,7 @@ class Float def ffi_yajl(yajl_gen, state) str = to_s if str == "NaN" || str == "Infinity" || str == "-Infinity" - raise ::FFI_Yajl::EncodeError.new("'#{str}' is an invalid number") + raise ::FFI_Yajl::EncodeError, "'#{str}' is an invalid number" end if state[:processing_key] if ( status = FFI_Yajl.yajl_gen_string(yajl_gen, str, str.bytesize) ) != 0 diff --git a/lib/ffi_yajl/ffi/parser.rb b/lib/ffi_yajl/ffi/parser.rb index e3226c0..67df934 100644 --- a/lib/ffi_yajl/ffi/parser.rb +++ b/lib/ffi_yajl/ffi/parser.rb @@ -23,12 +23,12 @@ module FFI_Yajl module FFI module Parser - def set_value(val) + def set_value(val) # rubocop:disable Style/AccessorMethodName case stack.last when Hash - raise FFI_Yajl::ParseError.new("internal error: missing key in parse") if key.nil? + raise FFI_Yajl::ParseError, "internal error: missing key in parse" if key.nil? if @opts[:unique_key_checking] && stack.last.key?(key) - raise FFI_Yajl::ParseError.new("repeated key: #{key}") + raise FFI_Yajl::ParseError, "repeated key: #{key}" end stack.last[key] = val when Array @@ -143,15 +143,15 @@ module FFI_Yajl ::FFI_Yajl.yajl_config(yajl_handle, :yajl_allow_partial_values, :int, 1) end - if ( stat = ::FFI_Yajl.yajl_parse(yajl_handle, str, str.bytesize) != :yajl_status_ok ) + if ( ::FFI_Yajl.yajl_parse(yajl_handle, str, str.bytesize) != :yajl_status_ok ) # FIXME: dup the error and call yajl_free_error? error = ::FFI_Yajl.yajl_get_error(yajl_handle, 1, str, str.bytesize) - raise ::FFI_Yajl::ParseError.new(error) + raise ::FFI_Yajl::ParseError, error end - if ( stat = FFI_Yajl.yajl_complete_parse(yajl_handle) != :yajl_status_ok ) + if ( ::FFI_Yajl.yajl_complete_parse(yajl_handle) != :yajl_status_ok ) # FIXME: dup the error and call yajl_free_error? error = ::FFI_Yajl.yajl_get_error(yajl_handle, 1, str, str.bytesize) - raise ::FFI_Yajl::ParseError.new(error) + raise ::FFI_Yajl::ParseError, error end stack.pop ensure diff --git a/spec/ffi_yajl/encoder_spec.rb b/spec/ffi_yajl/encoder_spec.rb index d8ee707..91009f4 100644 --- a/spec/ffi_yajl/encoder_spec.rb +++ b/spec/ffi_yajl/encoder_spec.rb @@ -29,12 +29,12 @@ describe "FFI_Yajl::Encoder" do let(:encoder) { FFI_Yajl::Encoder.new(options) } - it "encodes hashes in keys as strings", :ruby_gte_193 => true do + it "encodes hashes in keys as strings", ruby_gte_193: true do ruby = { { 'a' => 'b' } => 2 } expect(encoder.encode(ruby)).to eq('{"{\"a\"=>\"b\"}":2}') end - it "encodes arrays in keys as strings", :ruby_gte_193 => true do + it "encodes arrays in keys as strings", ruby_gte_193: true do ruby = { [0, 1] => 2 } expect(encoder.encode(ruby)).to eq('{"[0, 1]":2}') end @@ -102,7 +102,7 @@ describe "FFI_Yajl::Encoder" do end it "encodes symbols in keys as strings" do - ruby = { :thing => 1 } + ruby = { thing: 1 } expect(encoder.encode(ruby)).to eq('{"thing":1}') end @@ -190,7 +190,7 @@ describe "FFI_Yajl::Encoder" do end context "when validate_utf8 is off" do - let(:options) { { :validate_utf8 => false } } + let(:options) { { validate_utf8: false } } it "does not raise an error" do expect { encoder.encode(ruby) }.not_to raise_error diff --git a/spec/ffi_yajl/parser_spec.rb b/spec/ffi_yajl/parser_spec.rb index 968e0ee..750567f 100644 --- a/spec/ffi_yajl/parser_spec.rb +++ b/spec/ffi_yajl/parser_spec.rb @@ -87,7 +87,7 @@ describe "FFI_Yajl::Parser" do let(:json) { '{"key": /* this is a comment */ "value"}' } context "when allow_comments is false" do - let(:options) { { :allow_comments => false } } + let(:options) { { allow_comments: false } } it "should not parse" do expect { parser }.to raise_error(FFI_Yajl::ParseError) @@ -95,7 +95,7 @@ describe "FFI_Yajl::Parser" do end context "when allow_comments is true" do - let(:options) { { :allow_comments => true } } + let(:options) { { allow_comments: true } } it "should parse" do expect(parser).to eq("key" => "value") @@ -115,7 +115,7 @@ describe "FFI_Yajl::Parser" do let(:json) { %{{"key": \n/*\n this is a multiline comment \n*/\n "value"}} } context "when allow_comments is false" do - let(:options) { { :allow_comments => false } } + let(:options) { { allow_comments: false } } it "should not parse" do expect { parser }.to raise_error(FFI_Yajl::ParseError) @@ -123,7 +123,7 @@ describe "FFI_Yajl::Parser" do end context "when allow_comments is true" do - let(:options) { { :allow_comments => true } } + let(:options) { { allow_comments: true } } it "should parse" do expect(parser).to eq("key" => "value") @@ -135,7 +135,7 @@ describe "FFI_Yajl::Parser" do let(:json) { %{{"key": \n// this is an inline comment\n "value"}} } context "when allow_comments is false" do - let(:options) { { :allow_comments => false } } + let(:options) { { allow_comments: false } } it "should not parse" do expect { parser }.to raise_error(FFI_Yajl::ParseError) @@ -143,7 +143,7 @@ describe "FFI_Yajl::Parser" do end context "when allow_comments is true" do - let(:options) { { :allow_comments => true } } + let(:options) { { allow_comments: true } } it "should parse" do expect(parser).to eq("key" => "value") @@ -152,14 +152,14 @@ describe "FFI_Yajl::Parser" do end context "when json is invalid UTF8" do - let(:json) { "[\"#{"\201\203"}\"]" } + let(:json) { "[\"\201\203\"]" } it "should not parse by default" do expect { parser }.to raise_error(FFI_Yajl::ParseError) end context "when :dont_validate_strings is set to true" do - let(:options) { { :dont_validate_strings => true } } + let(:options) { { dont_validate_strings: true } } it "should parse" do expect(parser).to eq(["\x81\x83"]) @@ -167,7 +167,7 @@ describe "FFI_Yajl::Parser" do end context "when :dont_validate_strings is set to false" do - let(:options) { { :dont_validate_strings => false } } + let(:options) { { dont_validate_strings: false } } it "should not parse" do expect { parser }.to raise_error(FFI_Yajl::ParseError) @@ -175,14 +175,14 @@ describe "FFI_Yajl::Parser" do end context "when :check_utf8 is set to true" do - let(:options) { { :check_utf8 => true } } + let(:options) { { check_utf8: true } } it "should not parse" do expect { parser }.to raise_error(FFI_Yajl::ParseError) end context "when :dont_validate_strings is set to true" do - let(:options) { { :check_utf8 => true, :dont_validate_strings => true } } + let(:options) { { check_utf8: true, dont_validate_strings: true } } it "should raise an ArgumentError" do expect { parser }.to raise_error(ArgumentError) @@ -190,7 +190,7 @@ describe "FFI_Yajl::Parser" do end context "when :dont_validate_strings is set to false" do - let(:options) { { :check_utf8 => true, :dont_validate_strings => false } } + let(:options) { { check_utf8: true, dont_validate_strings: false } } it "should not parse" do expect { parser }.to raise_error(FFI_Yajl::ParseError) @@ -199,14 +199,14 @@ describe "FFI_Yajl::Parser" do end context "when :check_utf8 is set to false" do - let(:options) { { :check_utf8 => false } } + let(:options) { { check_utf8: false } } it "should parse" do expect(parser).to eq(["\x81\x83"]) end context "when :dont_validate_strings is set to true" do - let(:options) { { :check_utf8 => false, :dont_validate_strings => true } } + let(:options) { { check_utf8: false, dont_validate_strings: true } } it "should parse" do expect(parser).to eq(["\x81\x83"]) @@ -214,7 +214,7 @@ describe "FFI_Yajl::Parser" do end context "when :dont_validate_strings is set to false" do - let(:options) { { :check_utf8 => false, :dont_validate_strings => false } } + let(:options) { { check_utf8: false, dont_validate_strings: false } } it "should raise an ArgumentError" do expect { parser }.to raise_error(ArgumentError) @@ -239,10 +239,10 @@ describe "FFI_Yajl::Parser" do end context "when symbolize_keys is true" do - let(:options) { { :symbolize_keys => true } } + let(:options) { { symbolize_keys: true } } it "should symbolize keys correctly" do - expect(parser).to eq(:key => 1234) + expect(parser).to eq(key: 1234) end end @@ -308,10 +308,10 @@ describe "FFI_Yajl::Parser" do end context "when symbolize_keys is true" do - let(:options) { { :symbolize_keys => true } } + let(:options) { { symbolize_keys: true } } it "should symbolize keys correctly" do - expect(parser).to eq(:"日本語" => 1234) + expect(parser).to eq(:"日本語" => 1234) # rubocop:disable Style/HashSyntax end if RUBY_VERSION.to_f >= 1.9 @@ -382,7 +382,7 @@ describe "FFI_Yajl::Parser" do end context "with allow_trailing_garbage" do - let(:options) { { :allow_trailing_garbage => true } } + let(:options) { { allow_trailing_garbage: true } } it "parses" do expect(parser).to eq("foo" => { "foo" => 1234 }) end @@ -474,7 +474,7 @@ describe "FFI_Yajl::Parser" do # NOTE: parsing floats with 8 million digits on windows has some kind of huge # perf issues likely in ruby and/or the underlying windows libs - context "when parsing big floats", :ruby_gte_193 => true, :unix_only => true do + context "when parsing big floats", ruby_gte_193: true, unix_only: true do let(:json) { '[0.' + '1' * 2**23 + ']' } it "parses" do @@ -482,9 +482,9 @@ describe "FFI_Yajl::Parser" do end end - context "when parsing long hash keys with symbolize_keys option", :ruby_gte_193 => true do + context "when parsing long hash keys with symbolize_keys option", ruby_gte_193: true do let(:json) { '{"' + 'a' * 2**23 + '": 0}' } - let(:options) { { :symbolize_keys => true } } + let(:options) { { symbolize_keys: true } } it "parses" do expect { parser }.not_to raise_error @@ -500,7 +500,7 @@ describe "FFI_Yajl::Parser" do context "should raise an exception for repeated keys" do let(:json) { '{"foo":"bar","foo":"baz"}' } - let(:options) { { :unique_key_checking => true } } + let(:options) { { unique_key_checking: true } } it "should raise" do expect { parser }.to raise_error(FFI_Yajl::ParseError) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 147e124..9ec853d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -28,18 +28,18 @@ $LOAD_PATH << File.expand_path(File.join(File.dirname( __FILE__ ), "../lib")) begin require 'yajl' rescue LoadError - # yajl can't be installed on jruby + puts 'WARN: yajl cannot be loaded, expected if this is jruby' end require 'ffi_yajl' -RSpec.configure do |c| - c.filter_run_excluding :unix_only => true unless RUBY_PLATFORM !~ /mswin|mingw|windows/ - c.filter_run_excluding :ruby_gte_193 => true unless RUBY_VERSION.to_f >= 2.0 || RUBY_VERSION =~ /^1\.9\.3/ +RSpec.configure do |conf| + conf.filter_run_excluding unix_only: true unless RUBY_PLATFORM !~ /mswin|mingw|windows/ + conf.filter_run_excluding ruby_gte_193: true unless RUBY_VERSION.to_f >= 2.0 || RUBY_VERSION =~ /^1\.9\.3/ - c.order = 'random' + conf.order = 'random' - c.expect_with :rspec do |c| - c.syntax = :expect + conf.expect_with :rspec do |rspec| + rspec.syntax = :expect end end |