go - Go 编译器会“压缩”函数吗?
问题描述
我对我工作的公司的一位工程师问我的一个问题很感兴趣,关于是否有一个遍历数组并测试两个条件的单个函数或者有两个函数,每个函数都有一个条件更好。
我来这里问你们我的理由是否错误。
代码是这样的:
response := ListObjectsFromS3(bucket)
var filteredEmptyObjectsArray = utils.FilterEmptyObjects(response)
var filteredNonJson = utils.FilterNonJson(filteredEmptyObjectsArray)
每个功能是:
func FilterEmptyObjects(arrayToFilter []*Object) []*Object {
var filteredArray []*Object
for _, object := range arrayToFilter {
if *object.Size > 0 {
filteredArray = append(filteredArray, object)
}
}
return filteredArray
}
func FilterNonJson(arrayToFilter []*Object) []*Object {
var filteredArray []*Object
for _, object := range arrayToFilter {
if strings.HasSuffix(*object.Key, ".json") {
filteredArray = append(filteredArray, object)
}
}
return filteredArray
}
请原谅上面代码中的重复。它是一个玩具示例。
我不确切知道 Go 是如何优化这段代码的,但我认为它可能会将这两个函数“压缩”成这样的东西——当然,不是在 Go 代码中,但生成的机器代码将等同于:
func FilterSquashed(arrayToFilter []*Object) []*Object {
var filteredArray []*Object
for _, object := range arrayToFilter {
if strings.HasSuffix(*object.Key, ".json") && *object.Size > 0 {
filteredArray = append(filteredArray, object)
}
}
return filteredArray
}
响应的代码 - 也不是真正的 Go 代码,但编译器会生成一个机器码,相当于这样的东西:
response := utils.FilterSquashed(ListObjectsFromS3(bucket))
关键是,当我制作优化代码和非优化代码的 objdump 时,两者都将函数分开,并且CALL
每个函数都有一个。因此,我试图了解当前可能的优化深度或 Go 编译器决定坚持的优化深度。
让我知道你的想法
解决方案
您显示的“压缩”代码不等同于原始代码。代码优化的基本规则是优化和非优化代码的效果必须相同,但在您的示例中,您有两个函数应用不同的逻辑来过滤列表,第三个函数将应用第三种的逻辑,在这种特殊情况下会给你两个原始函数的组合,但不是在一般情况下。简而言之:在这种情况下,没有编译器会满足您的要求,因为语义不同。
在某些情况下内联某些函数时,编译器可能会发现更多优化,但我看不出您的示例如何从内联中受益。
推荐阅读
- c# - 绑定到 ViewModel 中的对象属性,或者如何使用具有相同属性名称的多个模型
- typescript - Vuex:处理列表和详细数据的最佳方式
- laravel - Vue 中的干预图像损坏
- python - 不使用 Key 属性的 DynamoDB 更新操作
- javascript - 如何使用 javascript 获取滚动条宽度(在最新的 chrome 中)
- r - 在while循环中使用next if正数
- python-3.x - Django 管理站点“int”在模型表单提交上没有 len() 错误
- sql - 仅跟踪工作日的连续缺勤天数 SQL
- regex - 在正则表达式中强制匹配文件名*= 超过文件名=
- ruby-on-rails - Rails 管理员:使用 `has_and_belongs_to_many` 会导致大量内存使用