按值传递参数的性能

performance of passing arguments by value

本文关键字:性能 参数 按值传递      更新时间:2023-10-16

在重构一些代码的过程中,想要更改类似的函数

bool A::function() {

return this->a == this->b || this->c == this->d || this->e == this->f || this->g == this->h ;
}

类似的东西

bool A::function(int a, int b, int c, int d, int e, int g) {

return a == b || c == d || e == this->f || g ==  this->h ;
}

该函数应该在主循环中每次调用,该主循环最多有10M个元素

与我一起工作的人不愿意使用第二个版本,因为通过6int的性能成本很高。考虑到循环的每次迭代都要经过大量代码,处理10M个元素大约需要1分钟,我确信这是可以忽略的。

一直按价值传递6分的成本这么高吗?如果没有,我怎么能让他们改变主意?

编辑:关于内联,我告诉他们,如果函数被内联,惩罚将为0,但他们的回答基本上是"我们不能确定它是否会被内联",我似乎记得这是真的(直到编译器)

我怀疑在经过合理优化的代码中,您不会看到这两种变体之间有任何大的区别。然而,证明这一点的是实际更改代码并比较不同的时间。(更重要的是,如果一分钟内处理1000万个条目,那么每个条目就需要6微秒,所以在现代处理器上大约有30000-200000条指令——我想说,添加6个参数传递不会以任何方式改变它——当然,除非这个函数在循环中被多次调用)。

是的,如果函数是内联的,那么两个选项的结果将是相同的代码——但你的同事说,你不能确定它是否是内联的吗——真正确定这一点的唯一方法是查看生成的机器代码(-S或使用objdump或类似的代码)。

在性能方面,我建议您对代码进行概要分析,看看是否存在重要的差异。传递int通常非常便宜,并且对自动优化开放,所以我怀疑你是否会看到可衡量的性能打击。

同样值得指出的是,这两种功能是不同的。第二个不一定使用成员变量,第一个使用。如果您总是比较成员变量,为什么要将它们作为参数传递?额外的不必要参数意味着更多的源代码和更大的bug范围。

编写代码,正如Shane所说,对其进行评测,或者我更喜欢获取一些堆栈样本,因为你可以准确地看到发生了什么。

如果在多个样本上,您在传递这些int参数的指令中找到程序计数器,那么它们将花费大量时间,您应该对此采取措施。

另一方面,样本可能会告诉你其他事情是主要的耗时因素,也许你应该先解决这个问题。然后程序会更快,如果你重新完成整个过程,它可能会回到你原来的问题。