• J
    Speed up xor_byte_strings by 70% · 8b10a941
    Jeremy Evans 提交于
    Benchmark:
    
    ```ruby
    require 'benchmark'
    require 'benchmark/ips'
    require 'securerandom'
    
    def xor_byte_strings(s1, s2) # :doc:
      s2_bytes = s2.bytes
      s1.each_byte.with_index { |c1, i| s2_bytes[i] ^= c1 }
      s2_bytes.pack("C*")
    end
    
    def xor_byte_strings_new(s1, s2) # :doc:
      s2 = s2.dup
      size = s1.bytesize
      i = 0
      while i < size
        s2.setbyte(i, s1.getbyte(i) ^ s2.getbyte(i))
        i += 1
      end
      s2
    end
    
    s1 = SecureRandom.random_bytes(32)
    s2 = SecureRandom.random_bytes(32)
    
    Benchmark.ips do |x|
      x.report("current"){xor_byte_strings(s1, s2)}
      x.report("new"){xor_byte_strings_new(s1, s2)}
      x.compare!
    end
    
    100000.times do |i|
      s3 = SecureRandom.random_bytes(32)
      s4 = SecureRandom.random_bytes(32)
      raise unless xor_byte_strings(s3, s4) == xor_byte_strings_new(s3, s4)
    end
    ```
    
    Results on ruby 2.5.1:
    
    ```
    Warming up --------------------------------------
                 current     6.519k i/100ms
                     new    10.508k i/100ms
    Calculating -------------------------------------
                 current     84.723k (_ 0.4%) i/s -    423.735k in   5.001456s
                     new    145.871k (_ 0.3%) i/s -    735.560k in   5.042606s
    
    Comparison:
                     new:   145870.6 i/s
                 current:    84723.4 i/s - 1.72x  slower
    ```
    8b10a941
request_forgery_protection.rb 17.9 KB