简体   繁体   中英

Why is modulo 3 inefficient?

I have this code here. This code is called 'efficient' because it is more efficient than modulo 3.

But why is modulo 3 inefficient? Does it not do the same operations underneath? Whats the complexity of modulo operation?

The asymptotic complexity is obviously the same (it is constant time). On the other hand, modulo 2 is very easy to implement in binary; modulo 3 is slightly more complicated.

Given any number n , n % 2 can be either 0 or 1 , so all you have to do is keep the value of the last bit. You can do this with one very simple binary AND:

n % 2 == n & 1

On the other hand, if you do n % 3 , all valid answers are (in binary) 00 , 01 and 10 . Notice that now the answer spans two bits; however, not all two bit numbers are valid (binary 11 cannot be the result of n % 3 ). For this reason, you need to do an extra operation:

// 3DEC == 11BIN, so (n & 3) keeps the last two bits of n. You
// then have to ensure that these last two bits are not both 1.
n % 3 == n & 3, if (n & 3) != 3

I don't know how modulo 3 is implemented in hardware, but regardless of how it is implemented, it is going to be slightly more complicated than modulo 2. That being said, it's silly to think that you can make a more efficient modulo operation in software than the one that is already available in hardware.

In the assembly level modulo is implemented with the instruction DIV which for large numbers can be slower than using logical operations, shifts and branches.

The DIV instruction (and it's counterpart IDIV for signed numbers) gives both the quotient and remainder (modulo). DIV r16 dives a 32-bit number in DX:AX by a 16-bit operand and stores the quotient in AX and the remainder in DX.

Does it not do the same operations underneath?

No, because the code is not correct: Try it out with input 21 and it will return false . However 21 % 3 is 0 .

21 is 0b10101 . That means the linked algorithm has oddCtr = 3 and and evenCtr = 0 after the while loop. Because 3 != 0 the algorithm returns false .

That java code does not translate to the same machine code. Shift and AND operations are faster than modulo in native code. The example code is parsed to native code and called every time is needed.

Here is a proof http://blog.teamleadnet.com/2012/07/faster-division-and-modulo-operation.html

Even so, you should not over optimize code over readability. Optimizations should be made only on critical components and after everything is set in place and the benefit can be measured practically not only in theory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM