2

I was doing some reading trying better to understand bitwise operators and came upon a helpful old blog post from 2012, which stated that - in an odd number test on a random, positive, integer x - evaluating x & 1 was 60% faster on the author's computer than evaluating x % 2. Stuff I've read elsewhere online (including on SO) seems to corroborate the bitwise operator being faster.

I've never written performance tests in jsperf before but I was interested to test this to see how much difference there was in Javascript. I was surprised to find, after testing across a few different browsers and devices, that modulo appeared to be faster more often than not.

Results

Chrome on Chromebook

Chrome on Chromebook

Chrome on Huawei P8

Chrome on Huawei P8

Chrome on Macbook Pro

Chrome on Macbook Pro

Firefox on Macbook Pro

Firefox on Macbook Pro

Safari on Macbook Pro

Safari on Macbook Pro

Safari on Macbook Air

Safari on Macbook Air

I ran each test a few times to check whether results were consistent. There were pretty consistent winners on FF and Chrome, although Safari did have more of a swing.

Since I have no experience in performance testing at all, have I written the tests badly wrong somehow? If not, could it be the case that modern devices and browsers somehow result in better performance for the modulus operator than for bitwise AND (or negligible difference in performance)? Is this even the appropriate way to benchmark this?

Or is there something else going on that I don't yet understand? (most likely!)

Liam
  • 27,717
  • 28
  • 128
  • 190
bigsee
  • 927
  • 8
  • 14
  • 1
    This smells of [Premature Optimisation](https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil) – Liam Sep 10 '18 at 10:58
  • 2
    I'm voting to close this question as off-topic because there are 3 scenarios where `&` is faster, and 3 where it is slower, so the premise "`&` is always faster" is clearly very wrong. – Peter B Sep 10 '18 at 11:05
  • @PeterB Only the Firefox 61 and Safari 11.0 results show any significant difference in speed. – Bergi Sep 10 '18 at 11:31
  • 2
    check the most upvoted SO Q&A https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array about branch misprediction, and try testing without `?:`/`if` conditional statements. Bitwise integer operators can process the bits independently, and will always be faster than floating point operation where bits depend on the results from other bits. – Slai Sep 10 '18 at 13:08
  • 1
    By the way `number % 2 == 1` is incorrect (only works for non-negative numbers) – harold Sep 10 '18 at 22:50
  • @Liam thank you for your comment. I am familiar with the concept of premature optimization, but I still considered this a question worth asking because the relative performance at the basic level of the two approaches might still be interesting for less experienced developers like me to be aware of, and I had not found any specific discussion of this for Javascript. Also, the top answer on that page states that, "anything that isn't a trivially clear optimization should be avoided until it can be measured" - which is precisely what I attempted in this case. – bigsee Sep 11 '18 at 11:34
  • 1
    @PeterB - thank you for the comment. I did consider your logic before asking the question. The reason I still considered it worth asking was that, as I stated, I've never used jsperf (or any similar tool before). Therefore, I assumed that mistake in my testing process - thereby invalidating the results - were just as likely as the hypothesis itself being proved true or false. This is also the reason for me adding the 'performance-testing' tag (perhaps incorrectly). – bigsee Sep 11 '18 at 11:37
  • @harold - thank you for your comment. I did mention in the original post that x is a "random, positive integer". Have I still made a mistake somewhere? :) – bigsee Sep 11 '18 at 11:39
  • @Slai thank you for your comment. link was interesting and I managed to follow. Thank you. Sorting and re-testing is certainly something I'll try. Didn't quite understand the final point about bits but will do some more research... :) – bigsee Sep 11 '18 at 11:50
  • 1
    Your misunderstanding that quote. It doesn't mean measurement for measurements sake. It means you've measured your **application** speed and identified that this operation is slowing your application significantly. The question you should be asking yourself is "Is the computation of a modulus a bottle neck in my application". If you don't know this is a waste of time. Spend your time improving something that does have an impact. – Liam Sep 11 '18 at 12:08
  • @Liam - thank you once again and for the extra question. This is not part of an application. This is - perhaps - knowledge for knowledge's sake, but, as I stated, the context was that I was reading up on bitwise operators, a subject I still no very little about. A blog post I read as part of my research made and assertion and so I wanted to test it. The results of the test surprised me (and a colleague), so I posed the question above to check whether my test methodology was flawed, or whether the assertion itself was wrong, since I think the answer useful knowledge. :) – bigsee Sep 11 '18 at 13:57
  • 1
    actually I mean to test just the operators without any extra code that might affect the time, but the results still seem inconsistent when run multiple times http://jsben.ch/dWcq8. `&` can process all bits of integer at the same time (but also needs some time to convert from float to integer), where other operators `*`. `/`, `%` need multiple steps. Modern browsers usually optimize for what is commonly used, and `%` is probably more common. In a way you are not measuring `&` vs `%`, but how well different browser versions can optimize. – Slai Sep 11 '18 at 13:58
  • @Liam P.S. the extra question you pose is a useful rule of thumb whenI'm actually writing an application rather than solely being curious though, so thank you very much! – bigsee Sep 11 '18 at 13:58
  • @Slai Yep I agree - I'm coming to the conclusion, as Strikegently's answer suggests, that the relative performance really end up being a factor of the engine in the browser in real life. Would be useful to know which browser optimise for what somehow, but I guess this is a rabbit hole as per Liam's point above. – bigsee Sep 11 '18 at 14:01

1 Answers1

1

I think you've answered your own question. Is it ALWAYS the case? Clearly not. Like many other things with JavaScript, the results are heavily dependent on the browser as each has their own engine or implementation.

Strikegently
  • 2,251
  • 20
  • 23
  • Thank you for this answer. I was wondering if an explanation was that the code would be running in the user's browser, but I (wrongly) assumed that where a testing tool ran pure Javascript that did not manipulate the DOM, it would run the code on a server somewhere. – bigsee Sep 11 '18 at 11:43