4

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

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 比 orTogether 快得多,所以我将使用 transform 方法。我很惊讶,orTogether2 在 MSVC9 发布模式下快了大约 4 倍。我运行了两次,第二次更改了顺序以确保它不是某种缓存问题,而是相同的结果。感谢大家的帮助。

4

5 回答 5

13

底部的将编译为与第一个有效的相同,您的 OR 函子肯定会被内联。因此,如果您需要添加更多灵活性或调试框架或其他任何东西,则第二个习惯用法会更加灵活。

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

于 2009-04-05T06:32:47.743 回答
5

拿起你的手表并测量

于 2009-04-05T06:34:46.740 回答
2

在我们了解如何MyBitwiseOrObject实施之前,确实没有太多选择。你为什么不做一些测试?

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

于 2009-04-05T06:32:19.930 回答
1

STL 提供的算法可以假设为

  1. 正确的
  2. 实施相当快
  3. 有执行复杂性保证(如果标准规定)

因此,使用它们不会出错。事实上,STL 实现者可能能够专门针对某些问题使用基于模板规范的更快实现。

于 2009-04-06T02:26:52.663 回答
0

你在预优化吗?你知道一个比另一个快吗?我怀疑它们非常接近相同。

也就是说,我会使用转换。让经过良好测试的库完成繁重的工作。保持你的代码简洁干净。您可能不知道 for-each 中到底发生了什么,但您可以相信库设计者做得很好。

于 2009-04-05T16:30:27.307 回答