Reputation: 83
I'm new to StackOverflow and looking for tips and helps tuning Pharo 5.0 in Windows Environment.
My PC is running Windows 10, CPU I5-4670K at 4 Ghz, and a Plextor 512G SSD as the C drive where Pharo 5.0 is loaded and running.
Below is a set of codes I used to understand Pharo's behaviors both in performance and computation precision.
| x y |
x := 0.
y := 400000000.
[1 to: 2000000000 do: [ :i |
x := x + 0.2]] timeToRun
took 2 minutes 8.281 seconds to execute. If I knock out one zero from the number of iterations, it took only 1.762 seconds to finish. 10 times more of the iterations used more than 70 times in execution time. It seems that I hit a system boundary such that the time for execution grow much higher than 10 times between the two cases.
Appreciate any tips and helps fine tuning Pharo 5.0 VM so I could reduce such unexpected and undesirable system behaviors?
p.s. During the execution, Windows Task Manager didn't report any changes of the disk activities. Pretty much the execution are all RAM and CPU operations. By the way, unless you have a much faster PC, please don't try to add another zero to the number of iterations, it took so long that I had to break the execution.
Upvotes: 4
Views: 233
Reputation: 14858
Welcome to SO (and to the smalltalk tag!)
First note that temporary y
is not playing any role here, so we can simplify a little bit the snippet to
| x |
x := 0.
[1 to: 200000000 * 10 do: [ :i |
x := x + 0.2]] timeToRun
which you compared against
| x |
x := 0.
[1 to: 200000000 * 1 do: [ :i |
x := x + 0.2]] timeToRun
The reason why the first version is not just 10
times slower that the second is that in the former the block variable i
moves from the SmallInteger
domain to the LargeInteger
one. So, every time the block increments i
, when i
has surpassed the SmallInteger
boundary, the addition i := i + 1
that takes place here involves LargeInteger
arithmetic, which is slower than the SmallInteger
one.
And how many times does the LargeInteger
arithmetics take place? Well, to calculate that we only need to subtract SmallInteger maxVal
from 200000000 * 10
:
(200000000 * 10) - SmallInteger maxVal = 926,258,177
meaning that Pharo is performing that number of operations on the large integer i
.
Note that if we had had instead
| x |
x := 0.
[
10 timesRepeat: [1 to: 200000000 * 1 do: [ :i | x := x + 0.2]]
] timeToRun
we would have spent about 10
times the speed of one iteration.
ADDENDUM
Please do not take the explanation above as suggesting that LargeInteger
arithmetics has a poor performance in Pharo. On the contrary, Pharo does a great job at making such computations efficient.
Behinds the scenes Pharo uses primitives for these operations while presenting the programmer with a unique and consistent view and API of Integer
arithmetics. In fact, if you try to do the same in another dialect with no VM support for LargeInteger
you will have to wait much (much) longer for the result to get calculated.
Upvotes: 6