-1

ベクター内のベクターのレベルが多すぎることを心配する必要がありますか? たとえば、5 レベルの階層があり、プロジェクト全体にこの種のコードがあります。

rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]

ここで、各要素はベクトルです。全体はベクトルのベクトルのベクトルです...これを使用すると、次のようにオブジェクトをコピーするよりもはるかに高速になります。

Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
// use b

2番目のアプローチははるかに優れていますが、遅いと思います。

これに関連するパフォーマンスの問題について心配する必要がある場合は、何か提案をしてください。

ありがとう

4

3 に答える 3

2

コードの効率は実際には影響を受けません (ベクター ランダム アクセスのコストは基本的に何もありません)。注意すべきことは、ベクター データ構造の悪用です。

これほど複雑なものに対して、クラスに対してベクトルを使用する必要がある理由はほとんどありません。適切に定義されたインターフェースを持つクラスは、コードをより効率的にするわけではありませんが、将来的にはメンテナンスがずっと簡単になります。

現在のソリューションも、未定義の動作に陥る可能性があります。たとえば、投稿したコードを見てください。

Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];

pos.apos.bpos.cによって参照されるベクトル インデックスpos.dがこれらのベクトルの 1 つに存在しない場合はどうなるでしょうか。未定義の動作に陥り、アプリケーションがセグメンテーション違反になる可能性があります (運が良ければ)。

これを修正するには、オブジェクトを取得する前にすべてのベクトルのサイズを比較する必要がありBlockます。

例えば

Block b;
if ((pos.a < rawSheets.size()) && 
    (pos.b < rawSheets[pos.a].countries.size()) &&
    (pos.c < rawSheets[pos.a].countries[pos.b].cities.size()) &&
    (pos.d < rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks.size()))
{
    b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
}

ブロックが必要になるたびに本当にそうするつもりですか?!!

あなたはそれを行うことができます、または少なくともクラスにまとめることができます...

例:

class RawSheet
{
    Block & FindBlock(const Pos &pos);

    std::vector<Country> m_countries;
};

Block & RawSheet::FindBlock(const Pos &pos)
{
    if ((pos.b < m_countries.size()) &&
        (pos.c < m_countries[pos.b].cities.size()) &&
        (pos.d < m_countries[pos.b].cities[pos.c].blocks.size()))
    {
        return m_countries[pos.b].cities[pos.c].blocks[pos.d];
    }
    else
    {
        throw <some exception type here>;
    }
}

次に、次のように使用できます。

try
{
    Block &b = rawSheets[pos.a].FindBlock(pos);

    // Do stuff with b.
} 
catch (const <some exception type here>& ex)
{
    std::cout << "Unable to find block in sheet " << pos.a << std::endl;
}

少なくとも、RawSheetクラス内でベクトルを引き続き使用できますが、メソッド内にあるため、他の場所のコードを変更することなく、後日ベクトルの乱用を削除できます (「デメテルの法則」を参照)!

于 2013-07-07T21:23:28.643 に答える
1

代わりに参照を使用してください。これはオブジェクトをコピーするのではなく、使いやすくするためにエイリアスを作成するだけなので、パフォーマンスには影響しません。

 Block& b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];

(アンパサンドを見てください)。b を使用すると、元のベクトルを操作することになります。

しかし、@delnanが指摘しているように、コード構造についてもっと心配する必要があります-より適切で保守可能な方法で書き直すことができると確信しています。

于 2013-07-07T21:01:12.863 に答える
-1

プログラムの制約が何であるか、またはそれが何をするかさえわからないので、特定の回答について心配する必要がありますか?

私たちが知っていることを考えると、あなたが与えたコードはそれほど悪くはありません。

あなたが示した最初と2番目のアプローチは機能的に同じです。どちらもデフォルトでオブジェクト参照を返しますが、割り当てによってはコピーが作成される場合があります。2番目は確かにそうです。

おそらくオブジェクトのコピーではなく参照が必要だという点で、サーシャは正しいです。使用方法によっては、const にしたい場合があります。

ベクターを使用しているため、各呼び出しは固定された時間であり、非常に高速である必要があります。本当に心配な場合は、通話の時間を計り、1 秒間に通話が行われる頻度を考慮してください。

また、データセットのサイズを考慮し、別のデータ構造 (おそらくデータベース) がより適切かどうかを検討する必要があります。

于 2013-07-07T21:13:04.733 に答える