Performance hit
Bob Arning
arning at charm.net
Thu Jul 30 19:57:30 UTC 1998
In doing some testing that involved Processes waiting on timers, I was puzzled by poor performance. Digging deeper I finally narrowed it down to this example:
PWatch class>>runTests3:
runTests3: howMany
| block alone done notAlone |
alone _ notAlone _ 0.
block _ [
Time millisecondsToRun: [100 timesRepeat: [howMany factorial]]
].
3 timesRepeat: [alone _ alone + block value].
done _ false.
[(Delay forSeconds: 30) wait. done _ true] forkAt: 6.
3 timesRepeat: [notAlone _ notAlone + block value].
[done] whileFalse.
Transcript show:
howMany asString,
' alone = ',(alone // 3) asString,
' notAlone = ',(notAlone // 3) asString; cr.
Then, when I evaluate:
5 to: 30 by: 5 do: [ :howMany | PWatch runTests3: howMany]
I get:
5 alone = 3 notAlone = 3
10 alone = 4 notAlone = 5
15 alone = 54 notAlone = 292
20 alone = 161 notAlone = 967
25 alone = 248 notAlone = 1661
30 alone = 379 notAlone = 2635
When we go from 10 factorial to 15 factorial (when the result crosses from SmallInteger to LargeInteger), performance drops by a factor of 5 or 6 *IF* another process is waiting on a timer to expire.
Looking at the interpreter source, after every primitive dispatch, there is
if (successFlag && ((nextWakeupTick != 0) && (((ioMSecs()) & 536870911) >= nextWakeupTick))) {
interruptCheckCounter = 1000;
checkForInterrupts();
}
There are comments (in the Mac version, anyway) as to there being two routines available for getting a millisecond clock value and that the more expensive is used for greater accuracy. Perhaps this might be a spot to use the cheaper variety with a suitable allowance for accuracy.
Any thoughts?
Cheers,
Bob
More information about the Squeak-dev
mailing list
|