これは、この MICの質問に対するフォローアップの質問です。参照ラッパーのベクトルにアイテムを追加するとき、選択した反復アプローチに関係なく、約 80% の時間を ++ 演算子内で費やします。
クエリは次のように機能します
VersionView getVersionData(int subdeliveryGroupId, int retargetingId,
const std::wstring &flightName) const {
VersionView versions;
for (auto i = 0; i < 3; ++i) {
for (auto j = 0; j < 3; ++j) {
versions.insert(m_data.get<mvKey>().equal_range(boost::make_tuple(subdeliveryGroupId + i, retargetingId + j,
flightName)));
}
}
return versions;
}
参照ラッパーを埋めるために次の方法を試しました
template <typename InputRange> void insert(const InputRange &rng) {
// 1) base::insert(end(), rng.first, rng.second); // 12ms
// 2) std::copy(rng.first, rng.second, std::back_inserter(*this)); // 6ms
/* 3) size_t start = size(); // 12ms
auto tmp = std::reference_wrapper<const
VersionData>(VersionData(0,0,L""));
resize(start + boost::size(rng), tmp);
auto beg = rng.first;
for (;beg != rng.second; ++beg, ++start)
{
this->operator[](start) = std::reference_wrapper<const VersionData>(*beg);
}
*/
std::copy(rng.first, rng.second, std::back_inserter(*this));
}
何をするにしても、演算子 ++ またはイテレータをインクリメントするだけの size メソッドの料金を支払います。つまり、まだ ++ で立ち往生しています。したがって、問題は、結果の範囲をより速く反復する方法があるかどうかです。そのような方法がない場合は、範囲を作成する代わりに結果で満たされる reference_wrapper のコンテナへの参照を保持する新しい引数を追加する equal_range の実装を試す価値がありますか?
編集 1: サンプル コード
http://coliru.stacked-crooked.com/a/8b82857d302e4a06/
このバグのため、Coliru ではコンパイルされません
編集 2: コール ツリー、演算子 ++ で費やされた時間
編集 3: いくつかの具体的なもの。まず第一に、operator++ が全体の実行時間に時間がかかりすぎるという理由だけでこのスレッドを開始しませんでした。単に「という理由で」好きではありませんが、現時点ではパフォーマンス テストの主要なボトルネックになっています。通常、各リクエストは数百マイクロ秒で処理されますが、これと同様のリクエスト (やや複雑です) は 1000 ~ 1500 マイクロ秒で処理され、それでも許容されます。元々の問題は、データ構造の項目数が数十万に達すると、パフォーマンスが 20 ミリ秒程度に低下することでした。MIC に切り替えた後 (コードの可読性、保守性、および全体的なエレガンスが大幅に改善されました)、リクエストごとに 13 ミリ秒程度に達することができ、そのうち 80% ~ 90% が operator++ に費やされました。これをどうにかして改善できるかどうか、それともタールと羽毛を探すべきかという質問です。:)