10

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?

Community
  • 1
  • 1
  • This one sounds familiar, I think it might be a duplicate. – Ali Afshar Mar 17 '09 at 18:37
  • I'm really hoping we can get a user voice request through to force peoples names to be put next the offensive tag if they click it. This is yet another case of abuse. – JaredPar Mar 17 '09 at 18:44
  • @JaredPar : To be fair, the OP berated everyone who asked him to clarify his question, it was fair to mark it as offensive because that was the only way to punish his abusive behavior. – George Stocker Mar 17 '09 at 18:45
  • Dup of http://stackoverflow.com/questions/226465/should-i-use-multiplication-or-division. – David Thornley Mar 17 '09 at 18:45
  • So do Python and .NET handle it the same way, David? – George Stocker Mar 17 '09 at 18:48
  • I spent so much time answering the first version of this question.. anyway, I did it again :) – Wadih M. Mar 17 '09 at 18:49
  • To be fair to the posters who spent time, the old question should be re-opened. – Brian R. Bondy Mar 17 '09 at 18:55
  • @Gortok, But I'm not seeing any abuse in this question. If someone is going to mark this question as offensive when the post itself does not appear to be (went through the revs didn't see anything obvious) they should at least give some context. – JaredPar Mar 17 '09 at 18:55
  • @JaredPar : The OP's question was marked offensive by 6 people because of his comments. This question obviously isn't offensive, and generally speaking, neither question should have been marked offensive. But the OP's comments should have been marked offensive. No mechanism to do that exists though – George Stocker Mar 17 '09 at 19:01
  • @Gortok: The question I referred to mentioned Python but didn't restrict itself to it, and the answer is almost certainly hardware-based, and the same in both cases. – David Thornley Mar 17 '09 at 19:03
  • @David Thornley : So MSIL doesn't handle it a certain way? – George Stocker Mar 17 '09 at 19:04
  • Wondering why the offensives were taken off this question, and the old original question remains locked/marked as offensive. I think a better solution would have been to re-open the other question and delete all comments that are offensive. The asker should have been respected instead of badgered. – Brian R. Bondy Mar 17 '09 at 19:08
  • So what is offensive about this question, Brian? – George Stocker Mar 17 '09 at 19:10
  • And can you see how he treated multiple people in the comments section? Or does it not show that? – George Stocker Mar 17 '09 at 19:11
  • @Gortok: I'll stay out of it. – Brian R. Bondy Mar 17 '09 at 19:13
  • @Brian : It's an honest question. If I don't know why this question is offensive, then I can't correct it, can I? If you voted it offensive, it'd help to know why. – George Stocker Mar 17 '09 at 19:15
  • @Gortok: My comment was referring only to the actions of the moderator, not about this question being offensive to me. – Brian R. Bondy Mar 17 '09 at 19:17
  • This question needs to be left up. You god damn mods are way too power trippy. You should be adding value instead of subtracting it. If half of the people with the power to edit/close fixed up posts instead of being anal and trying to close borderline questions SO would be better off. – mmcdole Mar 17 '09 at 19:22
  • @brian : When a question is deleted, it's automatically locked for a reason. One of the Uservoice requests covers that, IIRC. – George Stocker Mar 17 '09 at 19:22
  • @Simulcal : I agree whole-heartedly. I posted this question for that very reason, and RichB and I didn't vote to close this question, someone else did. – George Stocker Mar 17 '09 at 19:23
  • http://stackoverflow.uservoice.com/pages/general/suggestions/124889-offensive-posts-locked-not-deleted- – Michael Myers Mar 17 '09 at 19:28
  • @Gortok, oh I wasn't implying it was you. I'm just tired of coming into posts with downvotes/closevotes, say for example because the post was written by a non-native english speaker. There will be 2-3 mods in the comments section discussing why the post is bad instead of just fixing it. – mmcdole Mar 17 '09 at 19:31
  • @Gortok, you and RichB are both great mods. You aren't the norm though. – mmcdole Mar 17 '09 at 19:35
  • I will cast a re-open if someone explains why it's different from the question posted by @David Thornley – Brian R. Bondy Mar 17 '09 at 19:59
  • To be fair, I only re-posted this question, so I have no dog in this fight; but David Thornley's question didn't address how the MSIL handles this issue; and this one does. Technically, it's not a duplicate (at least not with how this crowd hates when I 'split hairs') – George Stocker Mar 17 '09 at 20:01
  • I think there's no answers that gives any MSIL specific reasoning. – Brian R. Bondy Mar 17 '09 at 20:03
  • @Brian R Bondy: Isn't that a fault of the answers, and not of the question ? Or should the question be made more precisely? – George Stocker Mar 17 '09 at 20:04
  • @Gortok: I think it probably indicates that the question reduces to the same thing. The other question is more general and this question is a subset of that topic. I could be wrong and MSIL handles this situation different from everyone else. – Brian R. Bondy Mar 17 '09 at 20:10
  • @Gortok: Perhaps indicate why you think that MISL behaves differently. – Brian R. Bondy Mar 17 '09 at 20:10
  • @Brian: If I knew the answer to that, I wouldn't need to ask the question... – George Stocker Mar 17 '09 at 20:22
  • @Gortok: lol, I meant indicate what urges you to be specific about MSIL. What can be gained from an MSIL specific answer that cannot from a general answer. Anyway I'm moving on. – Brian R. Bondy Mar 17 '09 at 20:28
  • Well, it'd help to know how the MSIL handles this particular issue; does it optimize before it even goes to Machine code? – George Stocker Mar 17 '09 at 20:32
  • @Gortok: I re-opened. Cheers. – Brian R. Bondy Mar 19 '09 at 18:16

11 Answers11

20

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.

mmcdole
  • 91,488
  • 60
  • 186
  • 222
dsimcha
  • 67,514
  • 53
  • 213
  • 334
  • 4
    A simple example: Raytracers need to do vector normalization or similar things for every ray (typically several times per pixel per frame). – schnaader Mar 17 '09 at 18:55
  • And if you're going for multiplication because you're executing it a bazillion times a second, nothing stopping you from adding a comment with the division value for readability. – Gloweye Jun 25 '19 at 07:54
11

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.

Walden Leverich
  • 4,416
  • 2
  • 21
  • 30
11

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.

H H
  • 263,252
  • 30
  • 330
  • 514
  • How can be multiplication and division faster then either of these two? – lacop Mar 17 '09 at 20:59
  • 4
    Because every compiler will do the (1 / 645.16) compile-time. So it just a different (and better) notation for 0.0015...0496 – H H Mar 17 '09 at 21:51
  • Oh, right, didn't see that. This is for sure nicer notation, +1. – lacop Mar 18 '09 at 14:33
5

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
  • 303,634
  • 46
  • 339
  • 357
4

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
  • 11,334
  • 2
  • 25
  • 33
  • 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 Mar 27 '09 at 11:19
3

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.
  • 12,810
  • 7
  • 47
  • 57
1

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

TrayMan
  • 7,180
  • 3
  • 24
  • 33
0

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
  • 76,898
  • 55
  • 205
  • 325
  • 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 Mar 17 '09 at 18:53
0

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
  • 36,249
  • 2
  • 81
  • 97
0

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
  • 1,213
  • 6
  • 12
0

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.

thkala
  • 84,049
  • 23
  • 157
  • 201
Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406