use*_*565 1 benchmarking smalltalk visualworks pharo gnu-smalltalk
一个以前的SO问题提出了有关这成语是在执行efficency方面更好的时间问题:
[ (var := exp) > 0 ] whileTrue: [ ... ]
Run Code Online (Sandbox Code Playgroud)
与
[ var := exp.
var > 0 ] whileTrue: [ ... ]
Run Code Online (Sandbox Code Playgroud)
直观地看,第一种形式似乎在执行期间更有效,因为它节省了一个额外的声明(第二种形式).在大多数Smalltalks中都是如此吗?
试着用两个愚蠢的基准测试:
| var acc |
var := 10000.
[ [ (var := var / 2) < 0 ] whileTrue: [ acc := acc + 1 ] ] bench.
| var acc |
var := 10000.
[ [ var := var / 2. var < 0 ] whileTrue: [ acc := acc + 1 ] ] bench
Run Code Online (Sandbox Code Playgroud)
显示两个版本之间没有重大差异.
还有其他意见吗?
所以问题是:我应该用什么来实现更好的执行时间?
temp := <expression>.
temp > 0
Run Code Online (Sandbox Code Playgroud)
要么
(temp := <expression>) > 0
Run Code Online (Sandbox Code Playgroud)
在像这样的情况下,得出结论的最好方法是在抽象层次上迈出一步.换句话说,我们需要更好地了解幕后发生的事情.
a的可执行部分CompiledMethod由其字节码表示.当我们保存一个方法时,我们正在做的是将它编译成一系列低级指令,以便VM能够在每次调用时执行该方法.那么,让我们来看看上面每个案例的字节码.
由于<expression>在两种情况下都是相同的,所以让我们大大减少它以消除噪音.另外,我们把我们的代码的方法,以便有一个CompiledMethod一起玩
Object >> m
| temp |
temp := 1.
temp > 0
Run Code Online (Sandbox Code Playgroud)
现在,让我们看看CompiledMethod它的超类是否有一些消息可以向我们展示字节码Object >> #m.选择器应包含子字节码,对吗?
...
在这里#symbolicBytecodes!现在让我们评估(Object >> #m) symbolicBytecodes得到:
pushConstant: 1
popIntoTemp: 0
pushTemp: 0
pushConstant: 0
send: >
pop
returnSelf
Run Code Online (Sandbox Code Playgroud)
请注意我们的temp变量如何Temp: 0在字节码语言中重命名为.
现在重复另一个并得到:
pushConstant: 1
storeIntoTemp: 0
pushConstant: 0
send: >
pop
returnSelf
Run Code Online (Sandbox Code Playgroud)
不同的是
popIntoTemp: 0
pushTemp: 0
Run Code Online (Sandbox Code Playgroud)
与
storeIntoTemp: 0
Run Code Online (Sandbox Code Playgroud)
这揭示了在两种情况下temp都以不同的方式从堆栈中读取.在第一种情况下,我们的结果从执行堆栈中<expression>弹出temp,然后temp再次按下以恢复堆栈.A pop后跟一个push相同的东西.在第二种情况下,相反,没有push或pop发生,temp只是从堆栈中读取.
所以结论是,在第一种情况下,我们将生成两个取消指令,pop然后是push.
这也解释了为什么差异如此难以衡量:push和pop指令有直接翻译成机器代码,CPU将执行它们的真快.
但请注意,没有什么能阻止编译器自动优化代码并实现其实pop + push相当于storeInto.通过这样的优化,Smalltalk片段将导致完全相同的机器代码.
现在,您应该能够决定您喜欢哪种形式.我认为这样的决定应该只考虑你更喜欢的编程风格.考虑到执行时间是无关紧要的,因为差异很小,并且可以通过实现我们刚才讨论的优化来轻松地减少到零.顺便说一下,对于那些愿意理解无与伦比的Smalltalk语言的低级领域的人来说,这将是一个很好的练习.