使用局部变量或多次访问struct值(C ++)

时间:2015-09-05 20:49:16

标签: c++ performance local-variables

在JS中,最好创建一个变量,以便重用,而不是访问深层对象结构中的值:

for (var i = 0, l = arr.length; i < l; ++i) {
  var someValueINeedOftenHere = arr[i].path.to.value;
  // do several things with this var..
}

因此,我们不是在这个深层对象结构中找到值,而是将它存储在本地,我们可以反复重复使用它。这应该是一个很好的做法,不仅因为它可以让你编写更干净的代码,而且还因为性能。

所以,当我编写C ++代码时,我会迭代一个包含很多结构/对象的向量。那么是相同的,还是没有关系?

2 个答案:

答案 0 :(得分:3)

一般来说,在C / C ++中并不重要。在C和C ++中,每个结构的内存布局在编译时都是已知的。当您键入arr[i].path.to.value时,它将与*(&arr[0] + i * (something) + offset_1 + offset_2 + offset_3)基本相同,并且所有这些都将在编译时简化为类似*(&arr[0] + i * (something) + something)的内容。那些something将由编译器计算并硬编码到二进制文件中,因此有效查找arr[i].path.to并不比arr[i].path.to.value快。

据我所知,这不是标准或其他任何规定,但大多数编译器实际上都是如此。

如果你想在某些特定的情况下确定一下,你可以看一下godbolt并查看它烹饪的组件:http://gcc.godbolt.org/

请注意,我假设在创建局部变量时,您正在引用值arr[i].path.to.value,这与您在javascript中的操作最相似。如果您实际将值复制到新变量,那么将产生一些复制开销。我不认为复制它会有利于w.r.t.缓存未命中,除非使用模式非常复杂。一旦你访问arr[i].path.to.value一次,它周围的所有东西都会在缓存中,并且没有理由将它复制到堆栈中会使任何事情变得更快。

答案 1 :(得分:0)

如果arrarr[i]pathtovalue都不涉及引用/指针,则无关紧要pointed out by Chris Beck

但是,如果arrarr[i]pathtovalue中的任何一个/ /涉及引用/指针,那么访问它们可能是缓存未命中。多次访问它们会导致多次缓存未命中(可能)。

直接将引用/指针存储到value可能比在追逐指针到达value时获得多个缓存未命中更有效。请记住,编译器可能会优化这样的事情。

如果将value存储为副本可能会更有效,如果它可以避免缓存未命中,并且复制起来相对较轻,并且您不需要修改原始值。同样,编译器很可能也会优化这些情况,如果它清楚这样做可以提高性能。

一切都取决于。 只有在已被证明存在问题时才进行优化