You are in: RPG Cafe > Which is better? x/2 or x*0.5
Short URL: https://ibm.biz/rpgcafe_div2_vs_mult_point_5
RPG Cafe: Divide by 2 or multiply by 0.5?
Which is better? Divide by 2 or multiply by 0.5?
I recently got a note from Ted Holt of Four Hundred Guru asking whether the old rule about multiplication being faster than division still applies for RPG on IBM i.
For example, if you want to divide by two, this rule suggests that multiplying by 0.5 is better.
I have known of this rule for a long time, and I have been automatically following it, without wondering whether it was still necessary. I was reminded of this blog post about performance tips. When I followed that rule, I hadn't been asking myself those questions.
So I ran a little test to see whether there's a difference. 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.
Does this performance difference matter?
Maybe, if you are dividing a million times in a loop. Probably not, if you are just doing a few divisions as part of other business logic, especially if you are reading or writing files. And if it's really important for a particular scenario, make sure it applies for that scenario - maybe division by 2 would be different from division by 257.3.
But wait ... there's more ...
There is an RPG scenario where it's better to multiply than divide, and that's in complex expressions that use RPG's default precision rules, where you want to divide by the result of a division.
x = y / (z / 100)
If you are using the default precision rules, the result of the z/100 division has a size of say 63,58, maximizing the number of decimal places to get the most accurate division result. When you then divide that value again, the result has a size of 63,0, with no decimal places.
Multiplying by 0.01 would give a more accurate result.
x = y / (z * 0.01)
Using the result-decimal-precisions rules also gives a more accurate result. Here's a program that demonstrates the problem and the two possible solutions.
The program is doing the following calculation.
(500 / (3 / 100)
According to the calculator on my computer, the answer is 16666.666666666666666666666666667.
Here's the program source
**free dcl-s x packed(25:5); dcl-s y packed(7:0) inz(500); dcl-s z packed(5:0) inz(3); x = y / (z / 100); dsply ('dft rules, / / : ' + %char(x)); eval x = y / (z * .01); dsply ('dft rules, / * : ' + %char(x)); eval(r) x = y / (z / 100); dsply ('(r) rules, / / : ' + %char(x)); eval(h) x = y / (z * .01); dsply ('oops, should use (h) : ' + %char(x)); return;
Here's what it displays:
DSPLY dft rules, / / : 16666.00000 DSPLY dft rules, / * : 16666.66666 DSPLY (r) rules, / / : 16666.66666 DSPLY oops, should use (h) : 16666.66667
The program I used for the performance test
The source for the program I used for the performance test is attached here. Most of it can be used as a template for similar tests.
It only tests one scenario at a time, so I can try what I expect is the faster scenario with more and more iterations until it runs long enough to be measurable. Then, I try what I expect is the slower scenario with the same number of iterations. Here's my session. The first four calls are running the first scenario, until there are enough iterations, 1000000, to register a meaningful amount of time. The last call runs the second scenario with the same number of iterations, 1000000.
5 > call perfchk (1000 m) DSPLY result = 39.45 DSPLY need more iterations 5 > call perfchk (10000 m) DSPLY result = 39.45 DSPLY need more iterations 5 > call perfchk (100000 m) DSPLY result = 39.45 DSPLY M 100000 times : .01 seconds. 5 > call perfchk (1000000 m) DSPLY result = 39.45 DSPLY M 1000000 times : .11 seconds. 5 > call perfchk (1000000 d) DSPLY result = 39.45 DSPLY D 1000000 times : 1.61 seconds.
15 January 2020