这是一个关于在#30449中描述的问题的概括。
假设我们有一个未导出的全局变量:
var myArray [4]T
并且对这个数组执行的所有操作都不满足以下条件:
- 让数组本身从包中逃逸(意味着变量是未导出的)
- 依赖于数组的可比性(例如,使用
==
或者将其作为Map键)
例如,允许的操作有索引(例如,myArray[3]
)和切片(例如,myArray[:]
)。
如果上述条件得到满足,我认为对于该数组不需要生成哈希/等效函数,因为它在包中被证明不会被使用,而且由于数组本身没有从包中逃逸,所以不能动态地使用。
这种用途的例子是:
var globalMessageTypes [2]protoimpl.MesageType // Desire no hash/eq functions for this type
func (T) Type() protoreflect.MessageType {
return &globalMessageTypes[0]
}
func (R) Type() protoreflect.MessageType {
return &globalMessageTypes[1]
}
func init() {
for i := range ... {
globalMessageTypes[i] = ...
}
}
我们声明globalMessageTypes
为一个数组,这样在索引全局数组时,T.Type
和R.Type
方法就不需要进行边界检查。然而,生成的哈希/等效函数会增加显著的二进制膨胀。
解决这个问题的方法是使用全局切片而不是数组,但这也有其他问题(参见#30529)。
4条答案
按热度按时间djmepvbi1#
然而,生成的哈希/等于函数会增加显著的二进制膨胀。
你是在谈论可执行文件的二进制大小吗?还是对象文件?我认为如果它们没有被调用,链接器会消除哈希/等于函数。
s3fp2yjn2#
话虽如此,我们可能应该修复编译器,使其一开始就不要生成它们。
frebpwbc3#
你是指可执行文件的二进制大小吗?还是对象文件?
肯定是对象文件,不确定二进制。我和neild遇到的问题是链接器出现了内存不足(OOM)的情况。导致OOM的原因有很多,但其中一个可能的原因是对象文件输入的大小,其中哈希/等式函数对膨胀贡献了一个不小的部分。
aij0ehis4#
@martisch