6

In programming we face various situations where we are required to make use of intermediate STL containers as the following example depicts:

while(true)
{
    set < int > tempSet;

    for (int i = 0; i < n; i ++)
    {
        if (m.size() == min && m.size() <= max)
        {
            tempSet.insert(i);
        }
    }
    //Some condition testing code
}

Or

set < int > tempSet;

while(true)
{
    for (int i = 0; i < n; i ++)
    {
        if (m.size() == min && m.size() <= max)
        {
            tempSet.insert(i);
        }
    }
    tempSet.clear();

    //Some condition testing code
}

Which approach is better in terms of time and space complexity considering the present state of C++ compliers?

4

10 に答える 10

15

最初のバージョンが正しいです。ほとんどすべての点でより簡単です。書きやすく、読みやすく、理解しやすく、保守しやすいなど...

2 番目のバージョンの方が速いかもしれませんが、そうではないかもしれませんそれを使用する前に、それが重要な利点を持っていることを示す必要があります。ほとんどの重要なケースでは、両者の間に測定可能なパフォーマンスの違いはないと思います。

組み込みプログラミングでは、スタックに物を置かないようにすることが役立つ場合があります。その場合、2 番目のバージョンが正しいでしょう。

デフォルトでは最初のバージョンを使用します。2 番目の方法は、そうする正当な理由を示すことができる場合にのみ使用してください (理由がパフォーマンスである場合は、メリットが大きいという証拠が必要です)。

于 2008-10-19T23:39:23.200 に答える
7

最初のものはよりバグに強いと言います。クリアすることを覚えておく必要はありません (スコープから外れて完了するだけです)。:-)

パフォーマンスに関しては大きな違いはありませんが、両方のケースを測定して自分で確認する必要があります。

于 2008-10-19T23:25:13.307 に答える
4

これが の問題であれば、set/map/list何の違いもありません。の質問であればvector/hash_set/hash_map/string、秒の方が速いか、同じ速度かのどちらかになります。もちろん、この速度の違いは、非常に多数の操作を実行している場合にのみ顕著になります (10,000vector回の int のプッシュは約 2 倍の速さでした - 3 秒といくつかの変更対 7 秒)。

データ構造へのポインターの代わりにデータ構造にa を格納するようなことをしている場合struct/class、サイズ変更のたびにすべての要素をコピーする必要があるため、この違いはさらに大きくなります。

繰り返しますが、ほとんどの場合、それは問題ではありません。問題がある場合でも、最適化を行っていて、あらゆるパフォーマンスに関心がある場合に表示されます。

于 2008-10-19T23:24:37.177 に答える
2

The second may be slightly better time-wise, but the difference will be extremely minimal -- the code still has to go through and release each of the items in the set, regardless of whether it's re-creating it or clearing it.

(Space-wise they'll be identical.)

于 2008-10-19T23:21:54.733 に答える
1

両者のパフォーマンスの違いはほとんどありません。コードの可読性と堅牢性に基づいて決定する必要があります。

最初の例の方が読みやすく安全だと思います - ループに条件を追加すると、6 か月後に何が起こるか、おそらくどこかに続行があります - 2 番目の例では、clear() をバイパスし、次のようになります。バグ。

于 2008-10-19T23:39:27.240 に答える
1

セットをスタックに置いているため、割り当てコストはほぼゼロです!

于 2008-10-19T23:50:37.560 に答える
0

原則として、コンテナへのデータのロードに関連するメモリ割り当てコストがあります。コンテナーを再利用することで、そのコストを何度も支払うことを避ける方がはるかに優れています。アイテムの数が実際にわかっている場合、または適切に推測できる場合は、事前にコンテナー内のスペースを割り当てておく必要があります。

オブジェクトをコンテナーに挿入する場合は特に顕著です。これは、コンテナーが小さすぎることを認識し、メモリを再割り当てし、新しいオブジェクトを新しいメモリ ベースにコピーして構築するため、多くの余分な構築/破棄コストを支払うことになる可能性があるためです。既存のオブジェクトで。

常に事前に割り当てて再利用します。時間とメモリを節約します。

于 2008-10-19T23:23:45.633 に答える
0

違いはほとんどありませんが、2番目のものはコンストラクターとデストラクタを複数回呼び出すことを回避しています。一方、最初のものは 1 行短く、コンテナーがループの範囲外に表示されないことを保証します。

于 2008-10-19T23:30:46.790 に答える
0

Set は通常、赤黒のツリーとして実装されます。各ノードは個別に割り当てられるため、セットは再利用の恩恵を受けません。そのため、両方のアプローチのパフォーマンスはほぼ同じです。「tempSet.clear()」の呼び出しには、オブジェクトの破棄とほぼ同じ時間がかかります。最初のアプローチは、同じパフォーマンスを持ち、より安全なプログラミング スタイルに従っているため、優れています。

ここで他のコンテナに関する一般的な議論を見つけることができます: Reusing a container o creating new one

于 2013-02-28T22:15:09.157 に答える
-1

STLコンテナに特定の数の要素を事前に割り当てることができると思います。したがって、コンテナに含まれる要素の数がわかっている場合、一定のメモリ割り当てコストがかかります。

于 2008-10-20T05:57:28.350 に答える