我有一个函数,只是将结构成员变量length
的值设置为1。在现代C ++中,这似乎不是良好的代码样式。可以用lambda完成吗?
void setEdgeLengths(Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> &edgeMap, std::vector<koalaGraph::PEdge>& E)
{
for (size_t i = 0; i < E.size(); i++) {
edgeMap[E[i]].length = 1;
}
}
我要问的原因是https://shaharmike.com/cpp/lambdas-and-functions/表明lambda将比普通函数更快。
在性能方面,Lambda也很棒。因为它们是对象而不是指针,所以它们很容易被编译器内联,就像仿函数一样。这意味着多次调用lambda(例如,使用std :: sort或std :: copy_if)比使用全局函数要好得多。这是C ++实际上比C更快的一个例子。
答案 0 :(得分:3)
除了给定的变量名之外,我认为以下代码是最佳的:
void setEdgeLengths(Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> &edgeMap, std::vector<koalaGraph::PEdge>& E)
{
for (const auto& e : E) {
edgeMap[e].length = 1;
}
}
根据需要设置(或忽略)花括号。
您可以将其中的任何一个或全部放入任意多个嵌套的lambda中,但这并没有增加更多的空格有用(但至少在调试版本中更有害)。您可能想问的是:
void setEdgeLengths(Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> &edgeMap, std::vector<koalaGraph::PEdge>& E)
{
std::for_each(E.begin(), E.end(), [&edgeMap](const auto& e) {
edgeMap[e].length = 1;
});
}
您不再有一个普通的循环(有些人认为这是好的样式),但是我认为代码没有变得更加清晰。这样做并没有使它更快-如果有的话,调试性能可能会略有下降。
现在,后一种形式 does 允许通过执行并行执行
std::for_each(std::execution::parallel, E.begin(), E.end(), [&edgeMap](const auto& e) {
,但这仅在您的edgeMap
正确处理并发访问时才合法。如果它是std::map
,则operator[]
可能会插入一个新元素(它不是线程安全的),因此如果没有进一步的假设,这将不是合法的优化。
答案 1 :(得分:1)
如果要将操作应用于容器的每个元素,则可以使用std::for_each
。由于您要使用E
的每个元素来访问edgeMap
,因此将在for_each
上使用E
,就像
Koala::AssocArray <koalaGraph::PEdge, Koala::DijkstraHeap::EdgeLabs<int >> edgeMap = /* stuff */;
std::vector<koalaGraph::PEdge> E = /* stuff */;
std::for_each(E.begin(), E.end(),[&](auto const& index){ edgeMap[index].length = 1; });