Should I use multiplication or division?

PerformanceProgramming Languages

Performance Problem Overview


Here's a silly fun question:

Let's say we have to perform a simple operation where we need half of the value of a variable. There are typically two ways of doing this:

y = x / 2.0;
// or...
y = x * 0.5;

Assuming we're using the standard operators provided with the language, which one has better performance?

I'm guessing multiplication is typically better so I try to stick to that when I code, but I would like to confirm this.

Although personally I'm interested in the answer for Python 2.4-2.5, feel free to also post an answer for other languages! And if you'd like, feel free to post other fancier ways (like using bitwise shift operators) as well.

Performance Solutions


Solution 1 - Performance

Python:

time python -c 'for i in xrange(int(1e8)): t=12341234234.234 / 2.0'
real    0m26.676s
user    0m25.154s
sys     0m0.076s

time python -c 'for i in xrange(int(1e8)): t=12341234234.234 * 0.5'
real    0m17.932s
user    0m16.481s
sys     0m0.048s

multiplication is 33% faster

Lua:

time lua -e 'for i=1,1e8 do t=12341234234.234 / 2.0 end'
real    0m7.956s
user    0m7.332s
sys     0m0.032s

time lua -e 'for i=1,1e8 do t=12341234234.234 * 0.5 end'
real    0m7.997s
user    0m7.516s
sys     0m0.036s

=> no real difference

LuaJIT:

time luajit -O -e 'for i=1,1e8 do t=12341234234.234 / 2.0 end'
real    0m1.921s
user    0m1.668s
sys     0m0.004s

time luajit -O -e 'for i=1,1e8 do t=12341234234.234 * 0.5 end'
real    0m1.843s
user    0m1.676s
sys     0m0.000s

=>it's only 5% faster

conclusions: in Python it's faster to multiply than to divide, but as you get closer to the CPU using more advanced VMs or JITs, the advantage disappears. It's quite possible that a future Python VM would make it irrelevant

Solution 2 - Performance

Always use whatever is the clearest. Anything else you do is trying to outsmart the compiler. If the compiler is at all intelligent, it will do the best to optimize the result, but nothing can make the next guy not hate you for your crappy bitshifting solution (I love bit manipulation by the way, it's fun. But fun != readable)

Premature optimization is the root of all evil. Always remember the three rules of optimization!

  1. Don't optimize.
  2. If you are an expert, see rule #1
  3. If you are an expert and can justify the need, then use the following procedure:
  • Code it unoptimized
  • determine how fast is "Fast enough"--Note which user requirement/story requires that metric.
  • Write a speed test
  • Test existing code--If it's fast enough, you're done.
  • Recode it optimized
  • Test optimized code. IF it doesn't meet the metric, throw it away and keep the original.
  • If it meets the test, keep the original code in as comments

Also, doing things like removing inner loops when they aren't required or choosing a linked list over an array for an insertion sort are not optimizations, just programming.

Solution 3 - Performance

I think this is getting so nitpicky that you would be better off doing whatever makes the code more readable. Unless you perform the operations thousands, if not millions, of times, I doubt anyone will ever notice the difference.

If you really have to make the choice, benchmarking is the only way to go. Find what function(s) are giving you problems, then find out where in the function the problems occur, and fix those sections. However, I still doubt that a single mathematical operation (even one repeated many, many times) would be a cause of any bottleneck.

Solution 4 - Performance

Multiplication is faster, division is more accurate. You'll lose some precision if your number isn't a power of 2:

y = x / 3.0;
y = x * 0.333333;  // how many 3's should there be, and how will the compiler round?

Even if you let the compiler figure out the inverted constant to perfect precision, the answer can still be different.

x = 100.0;
x / 3.0 == x * (1.0/3.0)  // is false in the test I just performed

The speed issue is only likely to matter in C/C++ or JIT languages, and even then only if the operation is in a loop at a bottleneck.

Solution 5 - Performance

If you want to optimize your code but still be clear, try this:

y = x * (1.0 / 2.0);

The compiler should be able to do the divide at compile-time, so you get a multiply at run-time. I would expect the precision to be the same as in the y = x / 2.0 case.

Where this may matter a LOT is in embedded processors where floating-point emulation is required to compute floating-point arithmetic.

Solution 6 - Performance

Just going to add something for the "other languages" option.
C: Since this is just an academic exercise that really makes no difference, I thought I would contribute something different.

I compiled to assembly with no optimizations and looked at the result.
The code:

int main() {
	
	volatile int a;
	volatile int b;
	
	asm("## 5/2\n");
	a = 5;
	a = a / 2;
	
	asm("## 5*0.5");
	b = 5;
	b = b * 0.5;
	
	asm("## done");
	
	return a + b;
	
}

compiled with gcc tdiv.c -O1 -o tdiv.s -S

the division by 2:

movl	$5, -4(%ebp)
movl	-4(%ebp), %eax
movl	%eax, %edx
shrl	$31, %edx
addl	%edx, %eax
sarl	%eax
movl	%eax, -4(%ebp)

and the multiplication by 0.5:

movl	$5, -8(%ebp)
movl	-8(%ebp), %eax
pushl	%eax
fildl	(%esp)
leal	4(%esp), %esp
fmuls	LC0
fnstcw	-10(%ebp)
movzwl	-10(%ebp), %eax
orw	$3072, %ax
movw	%ax, -12(%ebp)
fldcw	-12(%ebp)
fistpl	-16(%ebp)
fldcw	-10(%ebp)
movl	-16(%ebp), %eax
movl	%eax, -8(%ebp)

However, when I changed those ints to doubles (which is what python would probably do), I got this:

division:

flds	LC0
fstl	-8(%ebp)
fldl	-8(%ebp)
flds	LC1
fmul	%st, %st(1)
fxch	%st(1)
fstpl	-8(%ebp)
fxch	%st(1)

multiplication:

fstpl	-16(%ebp)
fldl	-16(%ebp)
fmulp	%st, %st(1)
fstpl	-16(%ebp)

I haven't benchmarked any of this code, but just by examining the code you can see that using integers, division by 2 is shorter than multiplication by 2. Using doubles, multiplication is shorter because the compiler uses the processor's floating point opcodes, which probably run faster (but actually I don't know) than not using them for the same operation. So ultimately this answer has shown that the performance of multiplaction by 0.5 vs. division by 2 depends on the implementation of the language and the platform it runs on. Ultimately the difference is negligible and is something you should virtually never ever worry about, except in terms of readability.

As a side note, you can see that in my program main() returns a + b. When I take the volatile keyword away, you'll never guess what the assembly looks like (excluding the program setup):

## 5/2

## 5*0.5
## done
    
movl	$5, %eax
leave
ret

it did both the division, multiplication, AND addition in a single instruction! Clearly you don't have to worry about this if the optimizer is any kind of respectable.

Sorry for the overly long answer.

Solution 7 - Performance

Firstly, unless you are working in C or ASSEMBLY, you're probably in a higher level language where memory stalls and general call overheads will absolutely dwarf the difference between multiply and divide to the point of irrelevance. So, just pick what reads better in that case.

If you're talking from a very high level it won't be measurably slower for anything you're likely to use it for. You'll see in other answers, people need to do a million multiply/divides just to measure some sub-millisecond difference between the two.

If you're still curious, from a low level optimisation point of view:

Divide tends to have a significantly longer pipeline than multiply. This means it takes longer to get the result, but if you can keep the processor busy with non-dependent tasks, then it doesn't end up costing you any more than a multiply.

How long the pipeline difference is is completely hardware dependant. Last hardware I used was something like 9 cycles for a FPU multiply and 50 cycles for a FPU divide. Sounds a lot, but then you'd lose 1000 cycles for a memory miss, so that can put things in perspective.

An analogy is putting a pie in a microwave while you watch a TV show. The total time it took you away from the TV show is how long it was to put it in the microwave, and take it out of the microwave. The rest of your time you still watched the TV show. So if the pie took 10 minutes to cook instead of 1 minute, it didn't actually use up any more of your tv watching time.

In practice, if you're going to get to the level of caring about the difference between Multiply and Divide, you need to understand pipelines, cache, branch stalls, out-of-order prediction, and pipeline dependencies. If this doesn't sound like where you were intending to go with this question, then the correct answer is to ignore the difference between the two.

Many (many) years ago it was absolutely critical to avoid divides and always use multiplies, but back then memory hits were less relevant, and divides were much worse. These days I rate readability higher, but if there's no readability difference, I think its a good habit to opt for multiplies.

Solution 8 - Performance

Write whichever is more clearly states your intent.

After your program works, figure out what's slow, and make that faster.

Don't do it the other way around.

Solution 9 - Performance

Do whatever you need. Think of your reader first, do not worry about performance until you are sure you have a performance problem.

Let compiler do the performance for you.

Solution 10 - Performance

If you are working with integers or non floating point types don't forget your bitshifting operators: << >>

    int y = 10;
    y = y >> 1;
    Console.WriteLine("value halved: " + y);
    y = y << 1;
    Console.WriteLine("now value doubled: " + y);

Solution 11 - Performance

Actually there is a good reason that as a general rule of thumb multiplication will be faster than division. Floating point division in hardware is done either with shift and conditional subtract algorithms ("long division" with binary numbers) or - more likely these days - with iterations like Goldschmidt's algorithm. Shift and subtract needs at least one cycle per bit of precision (the iterations are nearly impossible to parallelize as are the shift-and-add of multiplication), and iterative algorithms do at least one multiplication per iteration. In either case, it's highly likely that the division will take more cycles. Of course this does not account for quirks in compilers, data movement, or precision. By and large, though, if you are coding an inner loop in a time sensitive part of a program, writing 0.5 * x or 1.0/2.0 * x rather than x / 2.0 is a reasonable thing to do. The pedantry of "code what's clearest" is absolutely true, but all three of these are so close in readability that the pedantry is in this case just pedantic.

Solution 12 - Performance

Multiplication is usually faster - certainly never slower. However, if it is not speed critical, write whichever is clearest.

Solution 13 - Performance

I have always learned that multiplication is more efficient.

Solution 14 - Performance

Floating-point division is (generally) especially slow, so while floating-point multiplication is also relatively slow, it's probably faster than floating-point division.

But I'm more inclined to answer "it doesn't really matter", unless profiling has shown that division is a bit bottleneck vs. multiplication. I'm guessing, though, that the choice of multiplication vs. division isn't going to have a big performance impact in your application.

Solution 15 - Performance

This becomes more of a question when you are programming in assembly or perhaps C. I figure that with most modern languages that optimization such as this is being done for me.

Solution 16 - Performance

Be wary of "guessing multiplication is typically better so I try to stick to that when I code,"

In context of this specific question, better here means "faster". Which is not very useful.

Thinking about speed can be a serious mistake. There are profound error implications in the specific algebraic form of the calculation.

See Floating Point arithmetic with error analysis. See Basic Issues in Floating Point Arithmetic and Error Analysis.

While some floating-point values are exact, most floating point values are an approximation; they are some ideal value plus some error. Every operation applies to the ideal value and the error value.

The biggest problems come from trying to manipulate two nearly-equal numbers. The right-most bits (the error bits) come to dominate the results.

>>> for i in range(7):
...     a=1/(10.0**i)
...     b=(1/10.0)**i
...     print i, a, b, a-b
... 
0 1.0 1.0 0.0
1 0.1 0.1 0.0
2 0.01 0.01 -1.73472347598e-18
3 0.001 0.001 -2.16840434497e-19
4 0.0001 0.0001 -1.35525271561e-20
5 1e-05 1e-05 -1.69406589451e-21
6 1e-06 1e-06 -4.23516473627e-22

In this example, you can see that as the values get smaller, the difference between nearly equal numbers create non-zero results where the correct answer is zero.

Solution 17 - Performance

I've read somewhere that multiplication is more efficient in C/C++; No idea regarding interpreted languages - the difference is probably negligible due to all the other overhead.

Unless it becomes an issue stick with what is more maintainable/readable - I hate it when people tell me this but its so true.

Solution 18 - Performance

I would suggest multiplication in general, because you don't have to spend the cycles ensuring that your divisor is not 0. This doesn't apply, of course, if your divisor is a constant.

Solution 19 - Performance

As with posts #24 (multiplication is faster) and #30 - but sometimes they are both just as easy to understand:

1*1e-6F;

1/1e6F;

~ I find them both just as easy to read, and have to repeat them billions of times. So it is useful to know that multiplication is usually faster.

Solution 20 - Performance

Java android, profiled on Samsung GT-S5830

public void Mutiplication()
{
    float a = 1.0f;
    	
    for(int i=0; i<1000000; i++)
    {
        a *= 0.5f;
    }
}
public void Division()
{
    float a = 1.0f;
    
    for(int i=0; i<1000000; i++)
    {
        a /= 2.0f;
    }
}

Results?

Multiplications():   time/call: 1524.375 ms
Division():          time/call: 1220.003 ms

Division is about 20% faster than multiplication (!)

Solution 21 - Performance

There is a difference, but it is compiler dependent. At first on vs2003 (c++) I got no significant difference for double types (64 bit floating point). However running the tests again on vs2010, I detected a huge difference, up to factor 4 faster for multiplications. Tracking this down, it seems that vs2003 and vs2010 generates different fpu code.

On a Pentium 4, 2.8 GHz, vs2003:

  • Multiplication: 8.09
  • Division: 7.97

On a Xeon W3530, vs2003:

  • Multiplication: 4.68
  • Division: 4.64

On a Xeon W3530, vs2010:

  • Multiplication: 5.33
  • Division: 21.05

It seems that on vs2003 a division in a loop (so the divisor was used multiple times) was translated to a multiplication with the inverse. On vs2010 this optimization is not applied any more (I suppose because there is slightly different result between the two methods). Note also that the cpu performs divisions faster as soon as your numerator is 0.0. I do not know the precise algorithm hardwired in the chip, but maybe it is number dependent.

Edit 18-03-2013: the observation for vs2010

Solution 22 - Performance

After such a long and interesting discussion here is my take on this: There is no final answer to this question. As some people pointed out it depends on both, the hardware (cf piotrk and gast128) and the compiler (cf @Javier's tests). If speed is not critical, if your application does not need to process in real-time huge amount of data, you may opt for clarity using a division whereas if processing speed or processor load are an issue, multiplication might be the safest. Finally, unless you know exactly on what platform your application will be deployed, benchmark is meaningless. And for code clarity, a single comment would do the job!

Solution 23 - Performance

Here's a silly fun answer:

x / 2.0 is not equivalent to x * 0.5

Let's say you wrote this method on Oct 22, 2008.

double half(double x) => x / 2.0;

Now, 10 years later you learn that you can optimize this piece of code. The method is referenced in hundreds of formulas throughout your application. So you change it, and experience a remarkable 5% performance improvement.

double half(double x) => x * 0.5;

Was it the right decision to change the code? In maths, the two expressions are indeed equivalent. In computer science, that does not always hold true. Please read Minimizing the effect of accuracy problems for more details. If your calculated values are - at some point - compared with other values, you will change the outcome of edge cases. E.g.:

double quantize(double x)
{
    if (half(x) > threshold))
        return 1;
    else
        return -1;
}

Bottom line is; once you settle for either of the two, then stick to it!

Solution 24 - Performance

Well, if we assume that an add/subtrack operation costs 1, then multiply costs 5, and divide costs about 20.

Solution 25 - Performance

Technically there is no such thing as division, there is just multiplication by inverse elements. For example You never divide by 2, you in fact multiply by 0.5.

'Division' - let's kid ourselves that it exists for a second - is always harder that multiplication because to 'divide' x by y one first needs to compute the value y^{-1} such that y*y^{-1} = 1 and then do the multiplication x*y^{-1}. If you already know y^{-1} then not calculating it from y must be an optimization.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionedmunditoView Question on Stackoverflow
Solution 1 - PerformanceJavierView Answer on Stackoverflow
Solution 2 - PerformanceBill KView Answer on Stackoverflow
Solution 3 - PerformanceThomas OwensView Answer on Stackoverflow
Solution 4 - PerformanceMark RansomView Answer on Stackoverflow
Solution 5 - PerformanceJason SView Answer on Stackoverflow
Solution 6 - PerformanceCarson MyersView Answer on Stackoverflow
Solution 7 - PerformanceJames PodestaView Answer on Stackoverflow
Solution 8 - PerformanceJay BazuziView Answer on Stackoverflow
Solution 9 - Performancebuti-oxaView Answer on Stackoverflow
Solution 10 - PerformancesbeskurView Answer on Stackoverflow
Solution 11 - PerformanceGeneView Answer on Stackoverflow
Solution 12 - PerformanceDan HewettView Answer on Stackoverflow
Solution 13 - PerformanceToon KrijtheView Answer on Stackoverflow
Solution 14 - PerformancemipadiView Answer on Stackoverflow
Solution 15 - PerformanceSeamusView Answer on Stackoverflow
Solution 16 - PerformanceS.LottView Answer on Stackoverflow
Solution 17 - PerformanceChristopher LightfootView Answer on Stackoverflow
Solution 18 - PerformanceSteveView Answer on Stackoverflow
Solution 19 - PerformanceChrisView Answer on Stackoverflow
Solution 20 - PerformancePiotrKView Answer on Stackoverflow
Solution 21 - Performancegast128View Answer on Stackoverflow
Solution 22 - PerformanceJean-FrançoisView Answer on Stackoverflow
Solution 23 - Performancel33tView Answer on Stackoverflow
Solution 24 - PerformancematmaView Answer on Stackoverflow
Solution 25 - PerformancesatnhakView Answer on Stackoverflow