【问题标题】:How to write conditional for loop (if true loop through A, else loop through B)如何编写条件 for 循环(如果 true 循环通过 A,否则循环通过 B)
【发布时间】:2014-12-08 22:10:18
【问题描述】:

我做了一些搜索,但没有找到我真正想要的。

我有以下场景: 有两个不同类型的容器。例如,一个是vector<netIterator> A,另一个是list<netIterator *> B

if (c) 
  for loop on A { doingSth using the current netIterator; } 
else
  for loop on B { doingSth using the current netIterator; }

doingSth 现在大约需要 90 行。

如果我将其定义为内联函数,则无法正确内联,并且运行时损失巨大。 (添加更多测试数据: 使用非内联函数(大约有 12 个参数),运行时间为 300 秒;使用重复代码,运行时间约为 15 秒。 请注意,容器中有 150 万个元素。 )

有没有在不重复代码“doingSth”的情况下有效地循环基于c的A或B?

这是 C++,我们公司目前不允许使用 Boost 库。

感谢您的任何建议!

{在我发布问题一天后更新:

在同事的帮助下,我终于找到了运行时间增加的真正原因。不是因为函数没有内联,而是因为函数的两个向量参数是通过复制而不是通过引用传递的。在每个函数调用中,向量都被复制、构造、增长和销毁,这在 150 万次迭代中需要 300 秒。解决问题后,使用函数的运行时间可以忽略不计。

函数是由IDE使用“extract method”重构提取的,我认为这样做是正确的,并没有仔细检查参数列表,但实际上这次做得很糟糕。我以前确实用过,效果很好,但这次就不好了。

再次感谢大家对我的问题的回答和评论!这是我在这里的第一个问题,我得到答案的速度给我留下了深刻的印象(几分钟!)。我喜欢所有的答案,很高兴向你学习!

}

【问题讨论】:

  • 在 lambda 或完整函数中打包。
  • 我不明白为什么非内联函数会有巨大的运行时损失
  • 90 行代码不应内联。它可能没有性能提升。
  • 89 个 typedef 和 1 个指针添加可能会实现这一点。

标签: c++ for-loop


【解决方案1】:

当然有办法:

void f(bool c, vector<T>& a, list<T>& b) {
    auto lambda = [&](T& t) {/* your magic here */}
    if(c)
        for(auto&& x : a)
            lambda(x);
    else
        for(auto&& x : b)
            lambda(x);
}

你也可以对完整的功能做同样的事情。

但在您抱怨调用函数与内联函数的巨大运行时惩罚之前,请先测量和比较!
(自然,内联的二进制大小也是如此。)

【讨论】:

  • 是的!并使用[&amp;] 捕获在魔术的情况下是指一些局部变量。
【解决方案2】:

嗯。好吧,我想你可以做类似的事情

template<typename Container, typename Deref>
void loop_over(Container &container, Deref deref) {
  for(auto &&element_raw : container) {
    auto &&element = deref(element_raw);

    // doSth with element
  }
}

...

if(c) {
  loop_over(A, [](netIterator &i) { return  i; });
} else {
  loop_over(B, [](netIterator *i) { return *i; });
}

这应该给你代码的两个专业化。

不过,我很难相信未能内联 90 行代码会对性能产生巨大影响。您是否可靠地测量过这个?

【讨论】:

    猜你喜欢
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    相关资源
    最近更新 更多