-2

假设我们有这个结构

struct structure
{
    type element;
    int size;
}

我们是主要的,我们想要迭代一些东西。

是不是更快

for ( int i = 0; i < structure.size; ++i )

或者

int size = structure.size;
for ( int i = 0; i < size; ++i )

?

是否更重视第一种方法中对结构的连续绑定或额外的内存空间,以及在方法 n.2 的第一行中创建第一个变量所花费的时间?

我看不出他们两个之间有任何其他区别,所以如果你这样做,请分享!

编辑:我编辑了这个问题,所以现在简洁、简单、容易回答。请重新考虑你会给它的投票。谢谢你。

4

5 回答 5

3

可能有充分的理由选择其中一个。如果第一个示例中循环的内容改变了 , 的值structure.sizei将持续检查当前值。但是,在您的第二选择中,size不会像原来那样改变structure.size。你想要哪一个取决于问题。但是,我可能会size改为被调用initialSize

如果不是这种情况,您应该停止考虑这种次要的“优化”,而应该考虑什么是最易读的。我更喜欢第一个选择,因为它不会引入不必要的变量名。当你有两段代码做同样的事情时,相信编译器会找出最佳的方式来做这件事。告诉编译器你想让你的程序做什么是你的工作。编译器的工作是尽其所能做到这一点。

当且仅当您通过测量确定这是一项必要的优化(我无法想象它会永远如此),然后您才应该选择测量速度最快的优化。

于 2013-03-02T22:55:33.403 回答
0

您应该允许编译器进行这样的微优化。编写可读的代码,使其工作,然后如果它运行缓慢,则对其进行分析,并在真正需要的地方进行优化。

尽管在循环内调用函数的情况下,可以修改此结构并且编译器无法访问它的实现第二个变体可能会有所帮助,因为您向编译器提示它不需要从内存中重新加载 structure.size。我建议使用 const:

const int size = structure.size;
for ( int i = 0; i < size; ++i ) {
   somefunc( &structure );
}
于 2013-03-02T22:53:26.980 回答
0

编译后的代码不太可能与此有任何实际差异,除非它真的是一个具有真正垃圾优化的古老编译器。gcc、clang、MSVC 或英特尔的 C++ 编译器之类的任何东西都会为这些场景生成完全相同的代码。

当然,如果你在循环的条件内开始调用一个函数,而函数处理的数据被循环修改了,例如

std::string str;

cin >> str;
for(int i = 0; i < str.size(); i++)
{
    if (str[i] > 'a') 
       str+= 'B';
}

然后我们有一个不同的故事......

于 2013-03-02T22:55:05.857 回答
0

我不知道你对编译了解多少,但是在编译器的各个阶段中,有一个阶段叫做代码优化,它试图改进中间代码(通过执行各种优化技术,如死代码消除、循环转换等),以便可以生成运行速度更快的机器代码。

所以,实际上你的编译器会照顾你的头痛,我怀疑你会注意到任何性能问题。

于 2013-03-02T22:56:32.307 回答
-1

在您的第一种方法中,如果结构是引用或成员变量,它将无法正确存储到 CPU 缓存中,因为无法判断它是否在此块之外更改。

在您的第二种方法中,如size是当前代码块的局部变量,因此它将正确存储在缓存中。

因此,尽管创建了一个新变量,但第二种方法应该更快。

有关更完整的说明,请参阅Load-Hit-Store 。

于 2013-03-02T23:03:33.240 回答