go `cmd/compile:不必要的全局数组哈希/相等函数`

8nuwlpux  于 4个月前  发布在  Go
关注(0)|答案(4)|浏览(46)

这是一个关于在#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.TypeR.Type方法就不需要进行边界检查。然而,生成的哈希/等效函数会增加显著的二进制膨胀。
解决这个问题的方法是使用全局切片而不是数组,但这也有其他问题(参见#30529)。

djmepvbi

djmepvbi1#

然而,生成的哈希/等于函数会增加显著的二进制膨胀。
你是在谈论可执行文件的二进制大小吗?还是对象文件?我认为如果它们没有被调用,链接器会消除哈希/等于函数。

s3fp2yjn

s3fp2yjn2#

话虽如此,我们可能应该修复编译器,使其一开始就不要生成它们。

frebpwbc

frebpwbc3#

你是指可执行文件的二进制大小吗?还是对象文件?
肯定是对象文件,不确定二进制。我和neild遇到的问题是链接器出现了内存不足(OOM)的情况。导致OOM的原因有很多,但其中一个可能的原因是对象文件输入的大小,其中哈希/等式函数对膨胀贡献了一个不小的部分。

相关问题