I'm writing an application that is very JavaScript heavy (it's pretty much all JavaScript) and it does have a considerable amount of data to iterate through (JSON) and with this it must perform arithmetic certain tasks. Performance is a major consideration of the application. I have introduced Webworkers to help with this and I am trying not to fall back on methods provided by libs like jQuery (like .each()
instead of for
loops). Anyway, here's a simple question...
Within the application I have to apply price changes which will involve alot of numerical processes involving dividing. Baring in mind this will happen thousands and thousands of times would it be better for me to always apply a change by multiplication or a mixture of multiplication and division. For example I can apply a 50% discount by multiplying by 0.5 or dividing by 2.
I was always taught that division is slower than multiplication but I have no real proof of this… has anyone got an opinion on this before I start benchmarking and running test?
Multiplication is faster than division.
Yes, indeed, there is a difference. A loop with a million multiplies by 0.5 took 0.11 seconds and a loop with a million divides by 2 took 1.6 seconds. So it's true for the RPG (and probably for the IBM i) that multiplying is quicker than dividing.
Division is much slower, than multiplication.
It used to be that both multiplication and division were slow operations. Nowadays multiplication is a bit faster (but slightly slower than addition/subtraction), but division still is slower than the others.
Although both operations as very fast, multiply has a slightly better performance than the divide. In my tests (below), I noticed a 14% difference on Chrome and 10% difference on IE 9. If you must squeeze that performance from the browser, you can transform the divider to a multiplier before entering loops, but I don't think it is a good idea to compromise readability to such a tiny improvement.
var cnt = 500000;
var rls = []
var ags = [[2,1], [4,2], [7,3], [4e0,1], [32e0,2], [37e0,3], [-37e7,(7e3/3e-4)]];
var fns = [
{name: "fn_mul", fn: (function(x, y) { return x * y; })},
{name: "fn_div", fn: (function(x, y) { return x / y; })}
]
// setup ---------------------------------------
for(var iag=0; iag<ags.length; iag++) {
if(Object.prototype.toString.call(ags[iag]) !== "[object Array]") {
ags[iag] = [ags[iag]]
};
}
// run ------------------------------------------
for(var ifn=0; ifn<fns.length; ifn++) {
var fn = fns[ifn].fn;
var ts = (new Date()).valueOf();
for(var iag=0; iag<ags.length; iag++) {
var ag = ags[iag];
for(var icn=0; icn<cnt; icn++) { fn.apply(this, ag); }
}
rls.push({"name": fns[ifn].name, "ts": (new Date()).valueOf() - ts});
}
dump(rls);
To add a bit more context to this, provided that the compiler does not optimize divisions to multiplications (e.g. n / 2
gets converted to n * 0.5
), multiplications are always going to be faster than divisions.
This is due to how these operations are performed by the CPU:
See https://stackoverflow.com/a/1148060/520857 for reference to x86 (spoiler: fmul
is 2-3x faster than fdiv
)
See https://stackoverflow.com/a/17883319/520857 for reference to AMD (spoiler: fmul
is 7x faster than fdiv
)
The speeds of these operations are too fast to matter much IRL, but if you're doing a lot of them and you find that the compiler is not converting to multiplication (I don't think javascript engines do this, don't quote me on it though, a quick google check didn't give me any info on the topic), then it might make sense to make this optimization if you're encountering performance bottlenecks caused by divisions being too slow, which unlikely as you're more likely to be I/O bound than CPU bound in almost all applications.
edit: If you're performing lots of floating point calculations, you can consider finding a way to use your GPU to perform those operations as GPUs are significantly faster at FP ops than CPUs, to start you off from a quick google search again: http://gpu.rocks/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With