Should I use multiplication or division?

2019-01-02 20:36发布

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.

25条回答
公子世无双
2楼-- · 2019-01-02 20:42

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.

查看更多
若你有天会懂
3楼-- · 2019-01-02 20:44

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.

查看更多
裙下三千臣
4楼-- · 2019-01-02 20:45

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.

查看更多
忆尘夕之涩
5楼-- · 2019-01-02 20:46

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.

查看更多
只若初见
6楼-- · 2019-01-02 20:46

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!

查看更多
心情的温度
7楼-- · 2019-01-02 20:48

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.

查看更多
登录 后发表回答