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 倍高速でした。2 回実行し、2 回目は順序を変更して、ある種のキャッシュの問題ではなく、同じ結果であることを確認しました。みんな助けてくれてありがとう。

4

5 に答える 5

13

一番下のものは、最初のものと実質的に同じにコンパイルされます.ORファンクターは確実にインライン化されます. したがって、柔軟性やデバッグ フレームワークなどを追加する必要がある場合は、2 番目のイディオムの方が柔軟です。

前者にはメリットがないので、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 に答える