Go,封装和性能
Go, encapsulation and perfomance
我正在探索的代码:
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()
我保护了那些使用我的库的人免受不良使用,但它的成本 - 程序的性能?这其实不只是围棋
Shouldn't stack.Length()
become slower than stack.length
, because it is a function call?
Objection! Assumes facts not in evidence.
具体来说:
- 为什么你认为它是一个函数调用?它看起来像一个,但实际的Go编译器通常会扩展代码线.
- 为什么您认为函数调用比内联代码慢?在实际计算机上测量实际程序时,有时函数调用更快 比内联代码。事实证明,关键部分通常是正在执行的指令及其操作数是否已经在适当的 CPU 缓存中。有时,内联扩展函数会使程序 运行 变慢。
编译器应该进行内联扩展,除非它使程序 运行 变慢。编译器在预先或 post 方面有多好 - 检测这种减速(如果存在)是一个单独的问题。在这种特殊情况下,给定函数定义,编译器几乎肯定会直接扩展函数,因为访问 stack.length
可能是一条指令,调用函数将是一条指令,在这里决定权衡会很容易。
我正在探索的代码:
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()
我保护了那些使用我的库的人免受不良使用,但它的成本 - 程序的性能?这其实不只是围棋
Shouldn't
stack.Length()
become slower thanstack.length
, because it is a function call?
Objection! Assumes facts not in evidence.
具体来说:
- 为什么你认为它是一个函数调用?它看起来像一个,但实际的Go编译器通常会扩展代码线.
- 为什么您认为函数调用比内联代码慢?在实际计算机上测量实际程序时,有时函数调用更快 比内联代码。事实证明,关键部分通常是正在执行的指令及其操作数是否已经在适当的 CPU 缓存中。有时,内联扩展函数会使程序 运行 变慢。
编译器应该进行内联扩展,除非它使程序 运行 变慢。编译器在预先或 post 方面有多好 - 检测这种减速(如果存在)是一个单独的问题。在这种特殊情况下,给定函数定义,编译器几乎肯定会直接扩展函数,因为访问 stack.length
可能是一条指令,调用函数将是一条指令,在这里决定权衡会很容易。