diff options
author | murphy <murphy@rubychan.de> | 2011-05-28 22:12:03 +0000 |
---|---|---|
committer | murphy <murphy@rubychan.de> | 2011-05-28 22:12:03 +0000 |
commit | aef2852aff433b96d865330f23e5177460f5ffcc (patch) | |
tree | 9c8fe7edf1cb93399a34286855cc95f339c6d65d /etc/multicore/multi-slice-encoding-improved.rb | |
parent | 372d121b31b479461c399498bdd5285bad971c47 (diff) | |
download | coderay-aef2852aff433b96d865330f23e5177460f5ffcc.tar.gz |
multi-core benchmarks for EuRuKo 2011 talk
Diffstat (limited to 'etc/multicore/multi-slice-encoding-improved.rb')
-rw-r--r-- | etc/multicore/multi-slice-encoding-improved.rb | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/etc/multicore/multi-slice-encoding-improved.rb b/etc/multicore/multi-slice-encoding-improved.rb new file mode 100644 index 0000000..301589d --- /dev/null +++ b/etc/multicore/multi-slice-encoding-improved.rb @@ -0,0 +1,122 @@ +require 'strscan' +require 'benchmark' +require 'thread' + +class Scanner < StringScanner + + def initialize code + super code + end + + def tokenize encoder = Tokens.new + scan_tokens encoder + encoder + end + +protected + + def scan_tokens encoder + until eos? + if match = scan(/\s+/) + encoder.text_token match, :space + elsif match = scan(/\d+/) + encoder.text_token match, :number + elsif match = scan(/\w+/) + encoder.text_token match, :word + elsif match = scan(/[,.]/) + encoder.text_token match, :op + elsif scan(/\(/) + encoder.begin_group :par + elsif scan(/\)/) + encoder.end_group :par + else + raise + end + end + end + +end + + +class Encoder + + def setup + @out = '' + @opened = [] + end + + def finish + @out + end + + def encode scanner + setup + scanner.tokenize self + finish + end + + def text_token text, kind + if kind == :space + @out << text + else + text.gsub!(/[)\\]/, '\\\\\0') # escape ) and \ + @out << kind.to_s << '(' << text << ')' + end + end + + def begin_group kind + # @opened << kind + @out << kind.to_s << '<' + end + + def end_group kind + # @opened.pop + @out << '>' + end + +end + +size = ((ARGV.first || 1).to_f * 1_000_000).to_i # size + +# generate string +code = "2011 alpha, beta, (gamma), delta.\n" +code *= (size.to_f / code.size).ceil +code.slice! size..-1 + +slice_size = (ARGV[1] || 100).to_i +N = 1 + +1.times do + out = Encoder.new.encode(Scanner.new(code)) +end + +1.times do +2.times do + threads = [] + seconds = Benchmark.realtime do N.times do + chunk_offsets = [0] + code.lines.each_slice slice_size do |lines| + chunk_offsets << chunk_offsets.last + lines.join.bytesize + end + threads.clear + chunk_offsets.each_cons(2) do |this_chunk, next_chunk| + threads << Thread.new do + Thread.current[:out] = Encoder.new.encode Scanner.new(code[this_chunk...next_chunk]) + end + end + threads.each(&:join) + # out = threads.map { |t| t[:out] }.join + end end + + mb = N * size / 1_000_000.0 + puts 'Multi-Threaded: %0.1f MB in %0.2fs = %0.1f MB/s @ %d threads' % [mb, seconds, mb / seconds, threads.size] +end +2.times do + seconds = Benchmark.realtime do N.times do + out = Encoder.new.encode(Scanner.new(code)) + end end + + mb = N * size / 1_000_000.0 + puts 'Single-Threaded: %0.1f MB in %0.2fs = %0.1f MB/s' % [mb, seconds, mb / seconds] +end +end
\ No newline at end of file |