for (var i = 0, l = arr.length; i < l; ++i) {
var someValueINeedOftenHere = arr[i].path.to.value;
// do several things with this var..
}
因此,我们不是在这个深层对象结构中找到值,而是将它存储在本地,我们可以反复重复使用它。这应该是一个很好的做法,不仅因为它可以让你编写更干净的代码,而且还因为性能。
所以,当我编写C ++代码时,我会迭代一个包含很多结构/对象的向量。那么是相同的,还是没有关系?
答案 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)
如果arr
,arr[i]
,path
,to
,value
都不涉及引用/指针,则无关紧要pointed out by Chris Beck
但是,如果arr
,arr[i]
,path
,to
,value
中的任何一个/ /涉及引用/指针,那么访问它们可能是缓存未命中。多次访问它们会导致多次缓存未命中(可能)。
直接将引用/指针存储到value
可能比在追逐指针到达value
时获得多个缓存未命中更有效。请记住,编译器可能会优化这样的事情。
如果将value
存储为副本可能会更有效,如果它可以避免缓存未命中,并且复制起来相对较轻,并且您不需要修改原始值。同样,编译器很可能也会优化这些情况,如果它清楚这样做可以提高性能。
一切都取决于。 只有在已被证明存在问题时才进行优化。