質問内容
Optimize C++(第3版)10.6.1節に「整列済みデータの挿入はそうでないデータの挿入より高速である(要約)」との記述があり、自分でも実験してみたところ確かに数倍程度高速に動作しているようでした。
ただ書籍ではその理由については触れられていませんでした。自分の考えとしては、整列済みデータの挿入の方が木に偏りが生じやすく、その結果として回転操作の回数が多くなりむしろ遅くなると思っていたのでこの結果は不思議です。どなたか詳しい方がいらっしゃれば、この結果となる理由についてお知恵を拝借できないでしょうか。
該当のソースコード
測定に使用したコードを記載します。
500000要素の重複のないベクトルを生成し、それを前から順番に1つずつmapへinsertします。
cpp
1#include <algorithm> 2#include <chrono> 3#include <functional> 4#include <iostream> 5#include <map> 6#include <random> 7#include <set> 8#include <vector> 9 10using namespace std; 11 12void build_rnd_vector(vector<int>& v, unsigned int count) 13{ 14 default_random_engine e; 15 uniform_int_distribution<unsigned int> d(count, count * 10 - 1); 16 auto randamizer = bind(d, e); 17 set<int> unique; 18 v.clear(); 19 while (v.size() < count) { 20 unsigned int rv = randamizer(); 21 if (unique.insert(rv).second) { 22 v.push_back(rv); 23 } 24 } 25} 26 27int main() 28{ 29 ios::sync_with_stdio(false); 30 cin.tie(nullptr); 31 32 chrono::system_clock::time_point start, end; 33 34 int count = 5000000; 35 36 map<int, int> mp; 37 vector<int> v; 38 build_rnd_vector(v, count); 39 40 // 整列させる 41 sort(v.begin(), v.end()); 42 43 start = chrono::system_clock::now(); 44 for (int i = 0; i < v.size(); ++i) { 45 mp.insert({ v[i], i }); 46 } 47 end = chrono::system_clock::now(); 48 double elapsed = chrono::duration_cast<chrono::milliseconds>(end - start).count(); 49 50 cout << "Elapsed Sec " << elapsed << " msec\n"; 51 52 return 0; 53}
非整列データの場合は途中のsort()をコメントアウトして計測しました。
AtCoderのコードテストでC++20(gcc 12.2)で計測してみたところ、Elapsed Secは以下のような結果となりました。
非整列 | 整列済み |
---|---|
3884 | 1240 |
(msec)

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2025/07/22 19:05
2025/07/22 20:46 編集
2025/07/23 18:46