Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket masking: replace % 4 with & 0b11 for performance. #3100

Merged
merged 1 commit into from
Aug 5, 2016
Merged

Websocket masking: replace % 4 with & 0b11 for performance. #3100

merged 1 commit into from
Aug 5, 2016

Conversation

CodeSteak
Copy link
Contributor

@CodeSteak CodeSteak commented Aug 5, 2016

By replacing % 4 with & 0b11 websocket masking gets about 30% faster. This small change can make websockets up to 10% faster (in my testcase). This will become handy when binary websockets will be supported. (like in #2774)

For benchmark please run:

require "benchmark"

Benchmark.ips(warmup: 4, calculation: 10) do |x|

  buffer = MemoryIO.new(2048)
  buffer << "DaTA"*512
  slice = buffer.to_slice
  count = 2048
  mask = [1_u8,2_u8,3_u8,4_u8]

  x.report("mask_offset & 0b11") do
    mask_offset = 0

    count.times do |i|
       slice[i] ^= mask[mask_offset & 0b11]
       mask_offset += 1
     end
  end

  x.report("mask_offset % 4") do
    mask_offset = 0

    count.times do |i|
       slice[i] ^= mask[mask_offset % 4]
       mask_offset += 1
     end
  end
end
mask_offset & 0b11 297.81k (± 6.07%)       fastest
   mask_offset % 4 227.89k (± 8.37%)  1.31× slower

@asterite
Copy link
Member

asterite commented Aug 5, 2016

Thank you! ❤️

@asterite asterite merged commit bbdffc3 into crystal-lang:master Aug 5, 2016
@bew
Copy link
Contributor

bew commented Apr 11, 2017

Just to understand, why a simple change like this makes to code that faster?

@bcardiff
Copy link
Member

@bew usually some math operations can be expressed with bitwise operations that leads better preformance. (% are translated to LLVM's urem or srem), I wouldn't expect that much difference neither, but the benchmark has spoken.

@bew
Copy link
Contributor

bew commented Apr 12, 2017

Oh, I didn't spot the % vs & difference, I thought it was % 0b11, this explain! Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants