如何有效地更改向量中所有对象的成员数据? 给出了类对象指针的代码代码>,在现代C++中,改变对象成员数据的“首选”(最有效/性能/最简洁)方法是什么?当然,我可以使用for循环来迭代向量,但是使用for_each和lambda表达式是更好的选择吗?还有其他更好的方法吗

如何有效地更改向量中所有对象的成员数据? 给出了类对象指针的代码代码>,在现代C++中,改变对象成员数据的“首选”(最有效/性能/最简洁)方法是什么?当然,我可以使用for循环来迭代向量,但是使用for_each和lambda表达式是更好的选择吗?还有其他更好的方法吗,c++,performance,vector,c++17,C++,Performance,Vector,C++17,例如,,假设我们有vector successfulPeople,其中Person类包含两个成员变量boolsisHappy和isRich,对于successfulPeople中的所有Person对象,都需要将它们从false更改为truefor循环和for每个只是做相同的事情,但语法不同。如果您只是在容器中搜索一个元素,其他数据结构(如二叉树)可能会更有效,但无论是哪个容器,只要您需要在整个数据结构中循环,复杂性将是O(n)。当然,即使复杂度相同,但取决于数据结构的存储方式(即在连续内存中),

例如,,假设我们有
vector successfulPeople
,其中
Person
类包含两个成员变量bools
isHappy
isRich
,对于
successfulPeople
中的所有
Person
对象,都需要将它们从
false
更改为
true
<代码>for循环和
for每个
只是做相同的事情,但语法不同。如果您只是在容器中搜索一个元素,其他数据结构(如二叉树)可能会更有效,但无论是哪个容器,只要您需要在整个数据结构中循环,复杂性将是O(n)。当然,即使复杂度相同,但取决于数据结构的存储方式(即在连续内存中),速度也会有所不同。

从技术上讲,
对于每个
更可取,因为它允许指定其执行策略:

#include <algorithm>
#include <vector>
#include <execution>

int main() {
    std::vector<int> v{0, 1, 2};
    std::for_each(std::par_unseq, v.begin(), v.end(), [](int &x){ x += 40; });
}
#包括但不包括叮当声,例如


因此,尽管目前的标准建议每个
都可以(可能)表现得更好,但当前的现实选择实际上是一个带有
pragma的
for
-循环:-\

为什么您认为任何东西都会比for循环更高效?rangefor是“最佳”的,因为它最容易维护。好的,部分展开的循环、SIMD或并行(线程化)循环都比简单的循环更高效。但是C++优化器非常擅长转换代码(它们可以自动执行滚动和SIMD,并且并行循环只有一小部分代码>α-PracMMA OMP并行<代码>),如果你不得不问这个问题,编译器几乎肯定比你更能优化它。你的问题的基础是过早的优化。以一种正确且相当直接/惯用的方式编写代码;如果它被证明太慢,那么找出哪里太慢,然后处理它。事实上,我最关心的代码不是循环的类型;事实上,您正在循环一组指向该数据的指针,这很可能会破坏缓存一致性。如果这是性能关键的代码,那么第一步是直接使用
向量
。@Nicolas我已经有了一个完整的、有效的代码,并且对一些方面有疑问,我想深入研究我认为可以改进的领域——因此,这个问题。同样,一个原因是因为我习惯于
Mathematica
代码中不鼓励循环,所以我对它很好奇。我觉得问那些被认为是“简单的”/“明显的”问题真的会扼杀好奇心和羞耻感,这真的很不幸。指针向量的原因是因为我有一个唯一指针的主向量,这是一个包含对象子集的向量。感谢您的回复!你的答案中肯定有一些有趣的新内容,我以前从未遇到过。我们需要阅读更多关于每个
执行政策的
。正如我所说,我还没有看到它在任何地方得到实施,因此您的阅读将是一项长期投资-\当两个算法具有相同的复杂度顺序时(例如,在本例中为O(n)),那么前置因子就变得很重要:将特定的操作/计算减少2或4倍并不是一件坏事。然而,如果您只是像您的示例那样执行简单的布尔状态更新,那么您的速度就不会快很多,除非您将程序多线程化,除非您正在寻找答案。即使对于一些复杂的算术计算,使用SIMD也可能不会更快,因为SIMD严重依赖并行计算来减少时间,因此如果您的计算不是独立的,那么就没有什么帮助了。
$ clang -v -std=c++17 meow.cpp |& gawk '/execution/ { on = 1 } on || NR == 1 { print }' | sed 's/^/    /'
clang version 6.0.0 (tags/RELEASE_600/final)
meow.cpp:5:10: fatal error: 'execution' file not found
#include <execution>
         ^~~~~~~~~~~
1 error generated.

$ g++ -v meow.cpp |& tail -9 | sed 's/^/    /'
GNU C++17 (GCC) version 8.1.1 20180531 (x86_64-pc-linux-gnu)
    compiled by GNU C version 8.1.1 20180531, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c1584951f18917e503c3b4657c1f0dc5
meow.cpp:5:10: fatal error: execution: No such file or directory
 #include <execution>
          ^~~~~~~~~~~
compilation terminated.