我做了一些测试,其中我有两个场景,每个场景有两个相同的功能 - 一个通过引用传递参数,另一个通过值传递.带有字符串的场景显示了大量的性能提升(因为创建了一个字符串的副本,调用了构造函数),而使用long的测试在通过引用传递值时没有显示任何性能提升.事实上,有时表现更差.
这是原始类型的预期吗?没有必要通过引用传递它们吗?
我期待在不使用引用的情况下制作原始类型的副本,因此期望小的性能提升.
Ben*_*igt 29
通过值传递基元类型可以获得最佳性能.这是因为:
double而且long long比参考大最后一点经常被忽视,但可以产生相当大的差异.
是的,这是预期的行为.当您通过引用传递参数时,实际上是在传递变量的地址(就像使用指针一样).通常地址是一个4或8字节的整数,所以除非你的原始类型大于那个,否则你不会获得任何性能提升(即使它更大,你可能不会)
现代编译器非常聪明,因此,如果函数不是“隐藏的”(也就是说,在生成代码时编译器看不到的一部分),那么它可能根本就没有任何区别。但是,如果编译器遵循您的指令,则将简单类型作为引用传递可能会带来很大的不同。特别是如果该值在代码中多次更新。
我在工作的地方看到了一些代码,该代码是这样的:
void SomeClass::FindLength(int &len)
{
listEntry* list = theList; // theList is a member variable.
len = 0;
while (list)
{
len++;
list = list->next;
}
}
Run Code Online (Sandbox Code Playgroud)
通过更改代码来执行以下操作:
void SomeClass::FindLength(int &len)
{
listEntry* list = theList; // theList is a member variable.
int tempLen = 0;
while (list)
{
tempLen++;
list = list->next;
}
len = tempLen;
}
Run Code Online (Sandbox Code Playgroud)
整个代码的运行速度提高了约30%,并在很多地方调用(我认为中间有一些if条件,因此我们不能只跟踪长度)。并且由于它是API函数的一部分,因此无法更改函数签名。
使用该引用的速度较慢的原因是,每次更新时,编译器都会写入该引用值,这是从内存到寄存器,增量寄存器和存储寄存器到内存的负载。通过该tempLen解决方案,编译器可以使用寄存器,该寄存器要快得多。
| 归档时间: |
|
| 查看次数: |
14952 次 |
| 最近记录: |