func
にメモリを割り当てる関数を用意しましょうvec
。また、ループ内で let'sfunc
が何度も呼び出されます。
void func ()
{
std::vector<int> vec;
vec.resize(someNumber);
}
for (int i=0; i<someNumber; ++i)
{
func ();
}
vec
ループ内で一度だけメモリを割り当てるにはどうすればよいですか?
func
にメモリを割り当てる関数を用意しましょうvec
。また、ループ内で let'sfunc
が何度も呼び出されます。
void func ()
{
std::vector<int> vec;
vec.resize(someNumber);
}
for (int i=0; i<someNumber; ++i)
{
func ();
}
vec
ループ内で一度だけメモリを割り当てるにはどうすればよいですか?
私が見ることができる2つの可能な解決策があります。1 つは、使用できる への参照を関数に持たせるstd::vector<int>
ことです。
void func (std::vector<int> & vec)
{
vec.resize(someNumber);
}
もう 1 つの可能性は、プライベート ベクターを使用するファンクターを作成することです。したがって、複数回呼び出されると仮定して、割り当てを再利用できます。
class SomeFunctor
{
public:
void operator()();
private:
std::vector<int> vec;
}
void SomeFunctor::operator()()
{
vec.resize(someNumber);
}
これは次のように使用できます。
SomeFunctor func;
for (int i=0; i<someNumber; ++i)
{
func ();
}
vector の呼び出しresize()
は、vector が既存の要素に新しいストレージを割り当て、既存の要素をコピーし、古いストレージの割り当てを解除することを意味することに注意してください。これは、ベクトルの内部割り当てが再利用されないため、ベクトル オブジェクトを保持するという目的全体を無効にします。代わりに使用することを検討してくださいreserve()
。これは、割り当てを縮小することはありません (拡大する可能性があります)。
最適な解決策は、これらのアプローチのいずれでもなく、はるかに単純なものである可能性があります。あなたのサンプルコードは、これらのアプローチが有益かどうかを知るのに十分な詳細を提供していません.
補足として、時期尚早の最適化は悪いことであることを覚えておいてください。最初にコードを記述し、次にプロファイラーを実行して、ボトルネックがどこにあるかを確認します。通常、ボトルネックは、ユーザー入力の収集や、ネットワークやディスク I/O などのその他のものに関連しています。考えられるボトルネックを予測して、それらを回避しようとするべきではないと言っているわけではありませんが、考えられるすべての関数呼び出しと割り当て/割り当て解除について過度に心配する必要はありません。
これがプロトタイプではなく動作中のアプリケーションである場合は、プロファイラーを実行します。ボトルネックが他の場所にあることに気付く可能性は非常に高いです。
ベータが言ったように、関数が呼び出されるたびにfunc()
、新しいベクトルが作成され、関数が終了すると破棄されます。呼び出しごとにサイズが変更される単一のベクトルが必要な場合は、次のようなことを行うことができます。
std::vector<int> vec;
for (int i=0; i<someNumber; ++i)
{
vec.resize(i);
}
または、必要な最大メモリを使用してベクトルを直接初期化することもできます。
std::vector<int> vec(someNumber);