views:

770

answers:

11

When dealing with double data types is multiplying by the inverse better or worse?

Which way is faster? Which way uses less memory? Which way is preferred?

How does MSIL handle this?

SquareInches = MMSquared / 645.16 
SquareInches = MMSquared * 0.0015500031000062000124000248000496


NB: 10K users will note that this is a duplicate of this question, which was deleted because the original question asker decided to berate everyone in the 'comments' section of the question.

This question was reposted because it is a 'good' question.

Please 'uncheck' Community Wiki for your answer, as I'm only posting this as CW so that it's not seen as a 'reputation' grab.

Related Question:

Should I use multiplication or division?

+5  A: 

The answer will depend on the architecture of the executing environment. In general, divisions are usually slightly more costly than multiplication on most processors.

So unless this is actually a performance concern, I probably wouldn't worry about it. Pick the conversion factor that's more understandable.

John Feminella
The compiler does NOT optimize this because it could affect precision slightly.
dsimcha
You are right. I'll remove this line.
John Feminella
A: 

If you're dividing by a literal value like 645.16 then it's very likely that there is no difference because the compiler can easily determine which version is faster and use that.
If you're dividing or multiplying by a variable then it's likely that multiplication is slightly faster because the logic is generally more simple.
As with anything, to be sure, use a profiler.

shoosh
At least GCC -O2 on x86-32 does not perform such optimizations and does generate the fdivrs instruction. Such an optimization is full of potential pitfalls, so I doubt that many compilers do that.
TrayMan
A: 

Multiplies and adds are the fastest operations the processor supports. Some processors don't even have hardware implementations of things like division, square root, etc.

janneb
A: 

With most processors, it's faster to multiply than divide. But it's really insignificant for most applications, in my opinion you're better off with whichever is more readable, unless profiling shows it's a critical path.

If it's an interpreted language, the amount of time to read the source and convert it to numbers will overwhelm the time taken to actually do the math, especially if you use that many significant digits for the multiply. (Are you sure you really need that many significant digits?)

GoatRider
A: 

I would think the first method is clearly preferred because it is explicit. Imagine finding this in someone else's code. How are you sure that 0.00155... is really 1/645.16? What if the original programmer made a mistake? Furthermore, how do I know that 645.16 is the correct conversion factor? It's always best to not leave numbers compacted or represented in uniform for simplicity. The most basic example is as follows:

//hours per day * days per year int hoursPerYear = 24*365;

We can clearly see that this number is correct, but how would you know, offhand, that 8760 is the correct answer? If you need to perform many of these operations, you may want to preprocess the data to the correct form BEFORE entering your intensive calculations. In this manner, you won't need incredible efficiency, and the question becomes moot.

Stefan Kendall
+14  A: 

Multiplying by the inverse is faster. Compilers don't optimize this automatically because it can result in a small loss of precision. (This actually came up on a D newsgroup Walter Bright frequents, and he made it clear that compilers do not do this automatically.) You should normally divide because it is more readable and accurate.

If you are executing a piece of floating point code a billion times in a loop and you don't care about a small loss of precision and you will be dividing by the same number several times, then multiplying by the inverse can be a good optimization. I have actually gotten significant real world speedup in a few cases like the ones described by multiplying by the inverse, but these are extreme edge cases in loops executed several billion times that pretty much do nothing but multiply floats.

dsimcha
A simple example: Raytracers need to do vector normalization or similar things for every ray (typically several times per pixel per frame).
schnaader
+3  A: 

Division algorithms are slower than multiplication algorithms in most cases.

It's a tradeoff, you can choose either the more readable way, or the faster way.

// Using division operation
SquareInches = MMSquared / 645.16

This is easy to read and maintain, but performs slower than its multiplicative counterpart:

// Using a multiplication 
SquareInches = MMSquared * 0.0015500031000062000124000248000496

If you go this way, you'll need more space in memory to store the inverse number digits, but the algorithm runs substancially faster. A user tested it on a VS2005 project, and reported an 8X faster performance for the multiplicative version.

The reason for that is that a multiplication can be blindly converted to shift and add operations on the processor, which are the most optimized operations on a CPU. A good algorithm for signed multiplication is Booth's algorithm (the processor does this for you). On the other hand, more control overhead is required when performing a division algorithm, thus rendering division algorithms slower.

If performance is your need, use additions, substractions (nothing more than adding the two's complement), multiplications, shiftings, but never divisions. You'd get a substantial non-negligible improvement if you compute all your inverses in advance, and use them to multiply in a division intensive program.

Wadih M.
If both numbers are converted to double, then they use the same amount of memory.
quant_dev
+9  A: 

Which one is "faster" is indeed a cpu-specific issue, or at least how much faster is CPU specific, yes, division is typically seen as slower than multiplication. And of course all performance questions can be answered with "it depends."

HOWEVER, if you'd asked which is "better" rather than which is faster there would be a clear answer, the more readable one is better. The performance improvement you're looking at is likely on the order of several clock cycles, so unless you're talking about doing this millions of times, you're trying to save yourself microseconds. And there is no microsecond optimization that is worth sacrificing readability and maintainability.

WaldenL
+7  A: 

The benefit will be very small or zero, depending on both the compiler and the hardware.

But it could still matter (in a tight loop), and then for readability you should write

SquareInches = MMSquared * (1 / 645.16)

And preferably use a constant for 645.16.

Henk Holterman
How can be multiplication and division faster then either of these two?
lacop
Because every compiler will do the (1 / 645.16) compile-time. So it just a different (and better) notation for 0.0015...0496
Henk Holterman
Oh, right, didn't see that. This is for sure nicer notation, +1.
lacop
+1  A: 

Regarding compilers performing the optimization to mult, they can optimize this (GCC does): SquareInches = MMSquared * (1 / 645.16).

TrayMan
+3  A: 

from my VB code timer

Dim SquareInches As Double
Dim MMSquared As Double = 81
Const d As Double = 645.16
Const m As Double = 1 / 645.16
Private Function TestCase1() As Boolean 'One
    'Test One Code Here
    SquareInches = MMSquared / d
    'end test code
    Return True
End Function
Private Function TestCase2() As Boolean 'Two
    'Test Two Code Here
    SquareInches = MMSquared * m
    'end test code
    Return True
End Function

results

     3/17/2009 2:13:27 PM   CPU - 1.794GHz
 One - Using Division
 Two - Using Multiplication
 Outer Loops(OL)=7  Inner Loops=262,144
  ( times in ticks.  1 ms. = 10,000 ticks )
 >> Two faster, 0.0488 ticks/loop
  Ticks / Loop
 0.0342         0.0819         0.0331         0.0488
 OL Base        One            Two             One - Two
 1   8,936          21,459         8,609          12,850
 2   9,008          21,416         8,682          12,734
 3   8,965          21,423         8,643          12,780
 4   8,964          21,457         8,659          12,798
 5   8,966          21,469         8,640          12,829
 6   8,987          21,660         8,688          12,972
 7   8,963          21,429         8,802          12,627

  Average
 8,969          21,473         8,674          12,799
  Variance
 431.4          6,160.3        3,315.9       
  Standard Deviation
 20.8           78.5           57.6          
 3/17/2009 2:13:27 PM
dbasnett
wow. this is the gold metal winning answer
MikeJ
I wonder about the accuracy of this tick measurement.
quant_dev
as a relative measurement i guess it is ok. as an absolute measurement of time, that might be a different story. the times come from the Stopwatch class.
dbasnett