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

Use local variables or access multiple times a struct value ( C++ )

在 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++ 代码时,我必须遍历一个包含大量结构/对象的向量。那么是一样的,还是无所谓的?

一般而言,在 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 一次,它周围的所有东西都会在缓存中,并且没有理由将它复制到堆栈上会使任何事情变得更快。

arr的none、arr[i]pathtovalue、[=36=都没有关系] references/pointers,如.

但是,如果 arrarr[i]pathtovalue is/involves a reference/pointer然后访问它们可能是缓存未命中。多次访问它们会导致多次缓存未命中(可能)。

因此,将 reference/pointer 直接存储到 value 可能比在追逐指针到达 value 时获取多个缓存未命中更有效。请记住,编译器可能无论如何都会优化这样的事情。

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

这一切都取决于。 仅在证明存在问题时才进行优化