我是StackOverflow的新手,正在寻找技巧并帮助在Windows环境中调优Pharo 5.0。
我的电脑正在运行Windows 10,4 Ghz的CPU I5-4670K,以及装载和运行Pharo 5.0的C驱动器的Plextor 512G SSD。
以下是我用来理解Pharo在性能和计算精度方面的行为的一组代码。
| x y |
x := 0.
y := 400000000.
[1 to: 2000000000 do: [ :i |
x := x + 0.2]] timeToRun
花了2分8.281秒执行。如果我从迭代次数中剔除一个零,那么完成只需1.762秒。迭代次数超过执行时间的70倍以上。似乎我遇到了一个系统边界,这样两个案例之间的执行时间增长远远超过10倍。
感谢任何提示并帮助微调Pharo 5.0 VM,以便我可以减少这种意外和不受欢迎的系统行为?
P.S。在执行期间,Windows任务管理器没有报告磁盘活动的任何更改。几乎所有执行都是RAM和CPU操作。顺便说一句,除非你有一个更快的PC,请不要尝试在迭代次数上再添加一个零,花了这么长时间我不得不打破执行。
答案 0 :(得分:5)
欢迎使用SO(以及smalltalk标签!)
首先请注意,临时y
在这里没有扮演任何角色,所以我们可以简化一下片段
| x |
x := 0.
[1 to: 200000000 * 10 do: [ :i |
x := x + 0.2]] timeToRun
你与进行比较的
| x |
x := 0.
[1 to: 200000000 * 1 do: [ :i |
x := x + 0.2]] timeToRun
第一个版本不仅仅10
倍慢于第二个版本的原因是前者块变量i
从SmallInteger
域移动到{{1}一个。因此,每当块增加LargeInteger
时,当i
超过i
边界时,此处发生的加法SmallInteger
涉及i := i + 1
算术,这是慢于LargeInteger
。
SmallInteger
算术会发生多少次?好吧,要计算我们只需要从LargeInteger
中减去SmallInteger maxVal
:
200000000 * 10
意味着Pharo正在对大整数(200000000 * 10) - SmallInteger maxVal = 926,258,177
执行大量操作。
请注意,如果我们改为
i
我们花费的时间约为一次迭代的| x |
x := 0.
[
10 timesRepeat: [1 to: 200000000 * 1 do: [ :i | x := x + 0.2]]
] timeToRun
倍。
<强>附录强>
请不要将上面的解释视为表明10
算术在Pharo中表现不佳。相反,Pharo在使这样的计算有效方面做得很好。
幕后花絮Pharo使用基元进行这些操作,同时为程序员提供LargeInteger
算术的独特且一致的视图和API。事实上,如果你试图在另一个没有VM支持Integer
的方言中做同样的事情,你将不得不等待很长时间才能得到计算结果。