在下面的示例代码中,我分配了struct Chunk的一些实例。在for循环中,我遍历内存块并使用指针或引用访问不同的实例,并为它们分配一些随机数据。
但哪个for循环执行速度最快?根据我的知识,我会说参考循环将是最快的,因为它不需要解除引用并且可以直接访问内存中的实例。我有多错/对吗?
struct Chunk {
unsigned int a;
float b;
const char* c;
};
int main() {
Chunk* pData = new Chunk[8];
for( unsigned int i = 0; i < 8; ++i ) {
Chunk* p = &pData[i];
p->a = 1;
p->b = 1.0f;
p->c = "POINTERS";
}
for( unsigned int i = 0; i < 8; ++i ) {
Chunk& r = pData[i];
r.a = 1;
r.b = 1.0f;
r.c = "REFERENCES";
}
delete [] pData;
return 0;
}
答案 0 :(得分:10)
对于任何非白痴编译器,它们应该是相同的(不是大致相同,但完全相同)。在引擎盖下,引用是指针(在99%的编译器上)。没有理由有任何区别。
迂腐:第二个循环可能更快(可能不是),因为数据已经在缓存中,但就是这样。 :)
答案 1 :(得分:1)
任何体面的编译器生成的代码应该没有区别。
答案 2 :(得分:1)
如果您在代码的两个版本之间犹豫不决,那么您应该选择更具可读性的代码。您建议的那种可能的优化应该由编译器完成。
你的案例中更具可读性的是带引用的版本(实际上,可能不是更具可读性,但是共识是更喜欢使用引用,因为指针更多&#34;危险&#34;)。
但回到有效性:(如果有人知道汇编程序,请更好地停止阅读或冒着笑声攻击的风险......)在我看来,由于pData位于堆上,编译器必须使用它来编译它无论如何指针。我认为,如果你的结构只是在&#34; Chunk数据[8];&#34;中被分配在堆栈上,那么你的推理可能是正确的。但最迟在编译器优化时,应该删除差异。
答案 3 :(得分:1)
我很想说:谁在乎?速度的任何差异都将是 可以忽略不计,你应该选择最具可读性的。在这个特别的 case,我希望看到两者中生成的代码完全相同 案件。在更复杂的情况下,编译器可能无法 在循环中稍后确定指针尚未重新安装,以及 可能要重读它。但就这一点而言,你必须这样做 做足够的其他事情,差异是无法衡量的。
答案 4 :(得分:1)
执行时间几乎相同,但是使用引用的时间较少。