diff options
| author | murphy <murphy@rubychan.de> | 2011-04-17 15:37:52 +0000 | 
|---|---|---|
| committer | murphy <murphy@rubychan.de> | 2011-04-17 15:37:52 +0000 | 
| commit | 2d9ff211ebeef1ab4700e2b51e1e44b77e73a6b7 (patch) | |
| tree | be8c8324cb1653d4d88d0ff08d93fdcae5b8e492 /etc | |
| parent | 0203a17444d94b393ffce0e0a00f9abaaea06277 (diff) | |
| download | coderay-2d9ff211ebeef1ab4700e2b51e1e44b77e73a6b7.tar.gz | |
testing multi-threaded scanning
Diffstat (limited to 'etc')
| -rw-r--r-- | etc/speedup2/multi.rb | 138 | 
1 files changed, 138 insertions, 0 deletions
diff --git a/etc/speedup2/multi.rb b/etc/speedup2/multi.rb new file mode 100644 index 0000000..c32c140 --- /dev/null +++ b/etc/speedup2/multi.rb @@ -0,0 +1,138 @@ +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 matched = scan(/\s+/) +        encoder.text_token matched, :space +      elsif matched = scan(/!/) +        encoder.text_token matched, :not_going_to_happen +      elsif matched = scan(/=/)  #/ +        encoder.text_token matched, :not_going_to_happen +      elsif matched = scan(/%/) +        encoder.text_token matched, :not_going_to_happen +      elsif matched = scan(/\d+/) +        encoder.text_token matched, :number +      elsif matched = scan(/\w+/) +        encoder.text_token matched, :word +      elsif matched = scan(/[,.]/) +        encoder.text_token matched, :op +      elsif scan(/\(/) +        encoder.begin_group :par +      elsif scan(/\)/) +        encoder.end_group :par +      else +        raise +      end +    end +  end +   +end + + +class Tokens < Array +  alias token push +  alias text_token push +  alias block_token push +  def begin_group kind; push :begin_group, kind end +  def end_group kind; push :end_group, kind end +end + + +class Encoder +   +  def setup +    @out = '' +    @opened = [] +  end +   +  def finish +    while kind = @opened.pop +      close kind +    end +    @out +  end +   +  def encode scanner +    setup +    scanner.tokenize self +    finish +  end +   +  def token content, kind +    if content.is_a? ::String +      text_token content, kind +    elsif content.is_a? ::Symbol +      block_token content, kind +    else +      raise 'Unknown token content type: %p' % [content] +    end +  end +   +  def text_token text, kind +    @out << +      if kind == :space +        text +      else +        text.gsub!(/[)\\]/, '\\\\\0')  # escape ) and \ +        "#{kind}(#{text})" +      end +  end +   +  def block_token action, kind +    case action +    when :begin_group +      begin_group kind +    when :end_group +      end_group kind +    else +      raise +    end +  end +   +  def begin_group kind +    @opened << kind +    @out << "#{kind}<" +  end +   +  def end_group kind +    @opened.pop +    @out << '>' +  end +   +end + +N = (5 ** (ARGV.first || 8).to_i) +code = (1..N).map { |n| "#{n} alpha, beta, (gamma).\n" }.join + +time = Benchmark.realtime do +  out = Encoder.new.encode(Scanner.new(code)) +end +puts 'Current: %0.2fs -- %0.0f kTok/s' % [time, (N * 11 + 1) / time / 1000] + +slice_size = (ARGV[1] || 100).to_i +time = Benchmark.realtime do +  threads = [] +  code.lines.each_slice slice_size do |lines| +    threads << Thread.new do +      Thread.current[:out] = Encoder.new.encode(Scanner.new(lines.inject(&:+))) +    end +  end +  threads.each(&:join) +  out = threads.map { |t| t[:out] }.join +end +puts 'Multi-Threaded: %0.2fs -- %0.0f kTok/s' % [time, (N * 11 + 1) / time / 1000]  | 
