在这种情况下,我应该使用算法还是手工编码?

时间:2009-04-05 06:15:51

标签: c++ algorithm stl transform

好的,有人告诉我哪个更好。我需要| =一个向量的元素与另一个向量。也就是说,我想

void orTogether(vector<char>& v1, const vector<char>& v2)
{
    typedef vector<char>::iterator iter;
    for (iter i = v1.begin(), iter j = v2.begin() ; i != v1.end(); ++i, ++j)
        *i |= *j;
}

由于需要处理2个集合,我无法使用for_each。我想我可以做点像

struct BitWiseOr
{
    char operator()(const char& a, const char& b) {return a | b;}
};

void orTogether2(vector<char>& v1, const vector<char>& v2)
{
    transform(v1.begin(), v1.end(), v2.begin(), 
        v1.begin(), BitwiseOr());
}

这是一个更有效的解决方案,即使最上面的一个到位,但底部是分配?这是在处理循环的中间,我需要尽可能快的代码。

编辑:为BitwiseOr添加(明显?)代码。另外,我收到很多关于非相关事情的评论,例如检查v2的长度和更改名称。这只是一个例子,真正的代码更复杂。

嗯,我对两者进行了描述。 orTogether2比orTo快得多,所以我将继续使用转换方法。我很惊讶,或者在MSVC9发布模式下,Total2的速度提高了约4倍。我跑了两次,第二次更改顺序,以确保它不是某种缓存问题,但结果相同。感谢大家的帮助。

5 个答案:

答案 0 :(得分:12)

底部的编译与第一个编译有效相同,你的OR仿函数肯定会被内联。因此,如果您需要添加更多灵活性或调试框架或其他任何内容,第二个习语会更灵活。

由于第一个没有任何好处,请使用transform方法。一旦你养成这种习惯,你就会停止考虑所有应用程序的显式循环选择,因为它是不必要的。第一种方法的唯一优势是更容易向初学C ++程序员解释,他们对原始C更加熟悉。

答案 1 :(得分:5)

抓住你的手表并测量

答案 2 :(得分:2)

在我们了解MyBitwiseOrObject的实施方式之前,确实没有多少选择。你为什么不进行一些测试?

这里transform的问题是你需要一个单独的仿函数并在命名空间范围内定义它(远离它的使用位置)。 Lambda解决了这个问题 - 你可能想看看Boost Lambda Library。

答案 3 :(得分:1)

可以假设STL提供的算法是

  1. 正确
  2. 实施得相当快
  3. 具有执行复杂性保证(如果标准指定)
  4. 因此,使用它们不会出错。实际上,STL实现者可能能够针对某些问题专门使用基于模板规范的更快实现。

答案 4 :(得分:0)

您是否预先优化?你知道一个比另一个快吗?我怀疑他们很接近于一样。

那说,我会使用变换。让经过充分测试的图书馆完成繁重的工作。保持您的代码简单和干净。你可能不知道究竟什么在for-each中讨厌,但你可以相信图书馆设计师做得很好。