C ++避免了每次创建实例时为类方法分配内存。我的直觉是假设Go也减轻了这种重复。只是为了确认,Go是否只存储一次自定义结构的方法集?
type Custom struct {
value string
}
func (c Custom) TurnItUp() {
c.value = "up"
}
func (c Custom) TurnItDown() {
c.value = "down"
}
... // Many more methods defined for Custom.
// (Positive and negative directions in 100 dimensions)
func main() {
var many []Custom
fmt.Println("Memory: ", foo.memory()) // Measure memory used.
for i := 0; i < 10000; i++ {
append(many, Custom{value: "nowhere"})
}
fmt.Println("Memory: ", foo.memory()) // Measure memory used.
}
答案 0 :(得分:3)
当将具体类型分配给接口类型时,运行时会分配 itable 。具体类型和接口类型的 itable 将被缓存并用于以后的分配。
例如,此代码将分配一个itable:
type Volume interface {
TurnItUp()
TurnItDown()
}
var many []Volume
for i := 0; i < 10000; i++ {
many = append(many, Custom{value: "nowhere"})
}
此代码将分配两个itables,一个用于(Custom,Upper),另一个用于(Custom,Downer):
type Upper interface {
TurnItUp()
}
type Downer interface {
TurnItDown()
}
var uppers []Upper
var downers []Downer
for i := 0; i < 10000; i++ {
uppers = append(uppers, Custom{value: "nowhere"})
downers = append(downers, Custom{value: "nowhere"})
}
因为问题中的示例没有为接口分配自定义值,所以不会创建itables。
运行时使用静态元数据数据来构造itables。静态数据被分配并初始化一次。
有关详细信息,请参阅Go Data Structures: Interfaces。
答案 1 :(得分:3)
Bravada Zadada基本上回答了你的问题,但是在这里你是如何进行一项测试,显示某项行动导致的分配数量:
func TestMethods(t *testing.T) {
mem := testing.AllocsPerRun(10000000, func() {
_ = Custom{value: "nowhere"}
})
if mem != 0 {
t.Errorf("creating an object allocated %v memory", mem)
}
}
请参阅testing.AllocsPerRun
文档。您可以使用接口,指针方法和其他方法进行类似的测试。