From: Eric Mahurin Date: 2008-02-04T01:40:37+09:00 Subject: Re: [QUIZ] Parsing JSON (#155) ------=_Part_2606_30122446.1202056842394 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline On Feb 1, 2008 11:30 AM, ara howard wrote: > > On Feb 1, 2008, at 9:09 AM, Eric Mahurin wrote: > > > Maybe just have a little ruby > > script that generates a stream of repeatable random (but valid) JSON. > > cfp2:~ > cat a.rb > require 'rubygems' > require 'json' > The benchmark below has no gem dependencies, generates tests with deep structures, and has self-checking. It found a bug that the original unit tested didn't. By default, this benchmark keeps increasing the depth until the runtime is >= 1s. Also, I made some wrappers for the json and fjson gems to see how they perform. Here are the results on my machine: fjson: 224823 chars/second json(pure): 220289 chars/second json(ext): 1522250 chars/second require 'benchmark' class RandomJSON def initialize(value=0) @number = -1 @string = -1 @boolean = -1 @constant = -1 @value = value-1 end def number case (@number=(@number+1)%3) when 0 : 0 when 1 : 1234 when 2 : 3.75e+1 end end def string case (@string=(@string+1)%3) when 0 : "" when 1 : "JSON" when 2 : "\"\\\/\b\f\r\t" end end def boolean case (@boolean=(@boolean+1)%3) when 0 : false when 1 : true when 2 : nil end end def constant case (@constant=(@constant+1)%3) when 0 : number when 1 : string when 2 : boolean end end def array(depth) a = [] depth.times { a << value(depth-1) } a end def object(depth) o = {} depth.times { o[string] = value(depth-1) } o end def value(depth, v=nil) case (v||(@value=(@value+1)%3)) when 0 : array(depth) when 1 : object(depth) else constant end end end generator = RandomJSON.new((ARGV[1]||0).to_i) parser = JSONParser.new Benchmark.bm { |b| l = nil; t = nil 13.times { |depth| tree = generator.value(depth, depth%2) s = tree.inspect #puts s s.gsub!(/=>/, ':') s.gsub!(/nil/, 'null') tree2 = nil #puts s l = s.length t = b.report("#{depth} #{l}") { tree2 = parser.parse(s) } raise if tree2!=tree break if (t.real>=(ARGV[0]||1).to_f) } puts "#{(l/t.real).to_i} chars/second" } ------=_Part_2606_30122446.1202056842394--