Is Shifting Bits Faster Than Multiplying and Dividing in Java? .Net

Is shifting bits faster than multiplying and dividing in Java? .NET?

Most compilers today will do more than convert multiply or divide by a power-of-two to shift operations. When optimizing, many compilers can optimize a multiply or divide with a compile time constant even if it's not a power of 2. Often a multiply or divide can be decomposed to a series of shifts and adds, and if that series of operations will be faster than the multiply or divide, the compiler will use it.

For division by a constant, the compiler can often convert the operation to a multiply by a 'magic number' followed by a shift. This can be a major clock-cycle saver since multiplication is often much faster than a division operation.

Henry Warren's book, Hacker's Delight, has a wealth of information on this topic, which is also covered quite well on the companion website:

  • http://www.hackersdelight.org/

See also a discussion (with a link or two ) in:

  • Reading assembly code

Anyway, all this boils down to allowing the compiler to take care of the tedious details of micro-optimizations. It's been years since doing your own shifts outsmarted the compiler.

Is shifting bits faster than multiplying and dividing in Java? .NET?

Most compilers today will do more than convert multiply or divide by a power-of-two to shift operations. When optimizing, many compilers can optimize a multiply or divide with a compile time constant even if it's not a power of 2. Often a multiply or divide can be decomposed to a series of shifts and adds, and if that series of operations will be faster than the multiply or divide, the compiler will use it.

For division by a constant, the compiler can often convert the operation to a multiply by a 'magic number' followed by a shift. This can be a major clock-cycle saver since multiplication is often much faster than a division operation.

Henry Warren's book, Hacker's Delight, has a wealth of information on this topic, which is also covered quite well on the companion website:

  • http://www.hackersdelight.org/

See also a discussion (with a link or two ) in:

  • Reading assembly code

Anyway, all this boils down to allowing the compiler to take care of the tedious details of micro-optimizations. It's been years since doing your own shifts outsmarted the compiler.

Is shifting bits faster than multiplying and dividing in Java? .NET?

Most compilers today will do more than convert multiply or divide by a power-of-two to shift operations. When optimizing, many compilers can optimize a multiply or divide with a compile time constant even if it's not a power of 2. Often a multiply or divide can be decomposed to a series of shifts and adds, and if that series of operations will be faster than the multiply or divide, the compiler will use it.

For division by a constant, the compiler can often convert the operation to a multiply by a 'magic number' followed by a shift. This can be a major clock-cycle saver since multiplication is often much faster than a division operation.

Henry Warren's book, Hacker's Delight, has a wealth of information on this topic, which is also covered quite well on the companion website:

  • http://www.hackersdelight.org/

See also a discussion (with a link or two ) in:

  • Reading assembly code

Anyway, all this boils down to allowing the compiler to take care of the tedious details of micro-optimizations. It's been years since doing your own shifts outsmarted the compiler.

Is multiplication and division using shift operators in C actually faster?

Short answer: Not likely.

Long answer:
Your compiler has an optimizer in it that knows how to multiply as quickly as your target processor architecture is capable. Your best bet is to tell the compiler your intent clearly (i.e. i*2 rather than i << 1) and let it decide what the fastest assembly/machine code sequence is. It's even possible that the processor itself has implemented the multiply instruction as a sequence of shifts & adds in microcode.

Bottom line--don't spend a lot of time worrying about this. If you mean to shift, shift. If you mean to multiply, multiply. Do what is semantically clearest--your coworkers will thank you later. Or, more likely, curse you later if you do otherwise.

Bitwise shift vs Multiplication

I've loaded this VB code into decompiler ILSpy, and that was shown:

IL_0001: ldc.i4 255
IL_0006: stloc.0

// 255 * 256
IL_0007: ldloc.0
IL_0008: ldc.i4 256
IL_000d: mul.ovf
IL_000e: stloc.1 //equal part starts
IL_000f: ldloca.s 1
IL_0011: ldstr "X"
IL_0016: call instance string [mscorlib]System.Int32::ToString(string)
IL_001b: call void [System]System.Diagnostics.Debug::WriteLine(string)

// 255 << 8
IL_0021: ldloc.0
IL_0022: ldc.i4.8
IL_0023: ldc.i4.7
IL_0024: and
IL_0025: shl
IL_0026: conv.u1
IL_0027: stloc.2 //equal part starts
IL_0028: ldloca.s 2
IL_002a: ldstr "X"
IL_002f: call instance string [mscorlib]System.Int32::ToString(string)
IL_0034: call void [System]System.Diagnostics.Debug::WriteLine(string)

// cint(255) << 8
IL_003a: ldloc.0
IL_003b: ldc.i4.8
IL_003c: shl
IL_003d: stloc.3 //equal part starts
IL_003e: ldloca.s 3
IL_0040: ldstr "X"
IL_0045: call instance string [mscorlib]System.Int32::ToString(string)
IL_004a: call void [System]System.Diagnostics.Debug::WriteLine(string)

As you can see, 5 last strings of IL code are equal for each high-level instructions. Difference is only at top of each part. And 0xFF*256 contains only 3 operators, CInt(0xFF)<<8 contains 3 operators, and 0xFF<<8 contains 6 operators, i.e. 2 more times! Bitwise shift without type casting use bit mask for reject possible overflow, what appends additional operators into the IL code.

Also, i've found in the book of Francesco Balena "Programming Microsoft Visual Basic 2005: The language" that bitwise shift is faster for Long and ULong types. For Integer and Short types bitwise shift is equals to multiplication.

So my conclusion is:

  • for Long and ULong bitwise shift is faster than multiplication;

  • for all other types (with type cast to result bitness) multiplication is faster or equals to bitwise shift, so using of first or second case is only developer's taste.

Is It Worth Using Bitwise Operators In Methods?

You are asking the wrong question entirely. The question you should be asking is "should I keep my code simple and readable, or use tricks that I believe will improve its performance, even though I haven't measured its performance." The answer should be obvious.

Bitwise operators have their place, especially when you're dealing with binary file formats that need to pack a lot of data into small space. And it's absolutely critical to know how to mask out the high bits of a byte so that you don't accidentally sign-extend (print out these two variables to see what I mean):

byte b = (byte)0xDC;
int i = b & 0xFF;

But don't go looking for places to use these operators, especially to replace such simple tasks as dividing by 2.

Divide by 10 using bit shifts?

Editor's note: this is not actually what compilers do, and gives the wrong answer for large positive integers ending with 9, starting with div10(1073741829) = 107374183 not 107374182. It is exact for smaller inputs, though, which may be sufficient for some uses.

Compilers (including MSVC) do use fixed-point multiplicative inverses for constant divisors, but they use a different magic constant and shift on the high-half result to get an exact result for all possible inputs, matching what the C abstract machine requires. See Granlund & Montgomery's paper on the algorithm.

See Why does GCC use multiplication by a strange number in implementing integer division? for examples of the actual x86 asm gcc, clang, MSVC, ICC, and other modern compilers make.


This is a fast approximation that's inexact for large inputs

It's even faster than the exact division via multiply + right-shift that compilers use.

You can use the high half of a multiply result for divisions by small integral constants. Assume a 32-bit machine (code can be adjusted accordingly):

int32_t div10(int32_t dividend)
{
int64_t invDivisor = 0x1999999A;
return (int32_t) ((invDivisor * dividend) >> 32);
}

What's going here is that we're multiplying by a close approximation of 1/10 * 2^32 and then removing the 2^32. This approach can be adapted to different divisors and different bit widths.

This works great for the ia32 architecture, since its IMUL instruction will put the 64-bit product into edx:eax, and the edx value will be the wanted value. Viz (assuming dividend is passed in eax and quotient returned in eax)

div10 proc 
mov edx,1999999Ah ; load 1/10 * 2^32
imul eax ; edx:eax = dividend / 10 * 2 ^32
mov eax,edx ; eax = dividend / 10
ret
endp

Even on a machine with a slow multiply instruction, this will be faster than a software or even hardware divide.

Multiply by 0.5 rather than divide by 2

It's true that some (if not most) processors can multiply faster than performing a division operation, but, it's like the myth of ++i being faster than i++ in a for loop. Yes, it once was, but nowadays, compilers are smart enough to optimize all those things for you, so you should not care about this anymore.

And about bit-shifting, it once was faster to shift << 2 than to multiply by 4, but those days are over as most processors can multiply in one clock cycle, just like a shift operation.

A great example of this was the calculation of the pixel address in VGA 320x240 mode. They all did this:

address = x + (y << 8) + (y << 6)

to multiply y with 320. On modern processors, this can be slower than just doing:

address = x + y * 320;

So, just write what you think and the compiler will do the rest :)

What has a better performance: multiplication or division?

Well if it is a single calculation you wil hardly notice any difference but if you talk about millions of transaction then definitely Division is costlier than Multiplication. You can always use whatever is the clearest and readable.

Please refer this link:- Should I use multiplication or division?



Related Topics



Leave a reply



Submit