【发布时间】:2020-12-17 10:35:35
【问题描述】:
我正在探索的代码:
type Stack struct {
length int
values []int
}
func (s *Stack) Push(value int) {
// ...
}
func (s *Stack) Pop() int {
// ...
}
func (s *Stack) Length() int {
return s.length
}
方法Push 和Pop 更改Stack 结构中的length 字段。我想从其他文件中隐藏这个字段以防止像stack.length = ...这样的代码(手动length更改)。但是我需要有能力阅读这个领域,所以我添加了getter方法 - Length。
我的问题是:
stack.Length() 不应该比stack.length 慢,因为它是一个函数调用吗?我学了一点汇编,我知道程序调用一个函数应该做多少操作。我是否理解正确:通过添加 getter 方法 stack.Length() 我保护了那些使用我的库的人免受不良使用但它的成本 - 程序的性能?这实际上不仅涉及 Go。
【问题讨论】:
-
我向您保证,如果存在差异,则可以忽略不计。可能没有,因为编译器可能会内联对该方法的部分或全部调用。
-
您真的认为对静态结构字段的内联方法调用会影响(!)您的应用程序的性能吗?您是否有任何经验证据表明这是相关的?
-
@Volker 如果我这么写 - 你为什么要问“你真的这么想吗”?我解释了我这么认为的原因 - 汇编程序。如果您不明白我在说什么,请阅读
call命令。 -
@Don2Quixote Volker 不是那个意思。彼得和沃尔克都在暗示同样的意思,即使有性能增益;它可以忽略不计。编译器做了很多优化,可能会内联。
-
是的,你是对的,它会降低性能。但是,如果最高性能是唯一目标,那么您的实现应该如下所示:
type Stack struct {}; func (s *Stack) Push(_ int) {}; func (s *Stack) Pop() int {return 0}; func (s *Stack) Length() int {return 0),因为这是最快的实现,因为它将被优化器完全删除。不幸的是,这种实现有严重的缺点。一切都是妥协,有些妥协非常容易做出,因为一方的缺点完全可以忽略不计,这就是我试图解释的原因
标签: performance go compiler-optimization