More Related Content
PDF
20分くらいでわかった気分になれるC++20コルーチン PDF
PDF
PDF
PDF
PDF
PPTX
【Unity道場スペシャル 2017博多】クォータニオン完全マスター PDF
What's hot
PDF
数学カフェ 確率・統計・機械学習回 「速習 確率・統計」 PDF
PDF
PDF
Scala 初心者が米田の補題を Scala で考えてみた PDF
中3女子が狂える本当に気持ちのいい constexpr PDF
PDF
PDF
Unreal Engine 4を使って地球を衛る方法 PDF
バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~ PDF
PPTX
猫でも分かる UE4のAnimation Blueprintの運用について PDF
PDF
PDF
PDF
PDF
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する PPTX
PDF
PPT
PDF
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ Similar to Map
PDF
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30) PDF
PDF
C++0x in programming competition PDF
PDF
PPTX
PDF
PDF
ODP
PPT
C++0x in programming competition PDF
PDF
PDF
PDF
PDF
PPTX
Boost.PropertyMap (.pptx) PDF
PDF
PDF
Data-Intensive Text Processing with MapReduce ch4 PPTX
Introduction to Functional Programming Map
- 1.
- 2.
std::map をfor で回したことがある
std::map::lower_bound を使わない
map::find より map::begin をよく使う
面倒だし std::map でも全探索する
- 3.
速度が重要だと考えているなら、今すぐ
std::map の全走査はやめましょう
std::list より、さらに遅い
赤黒木で実装されているので仕方ない
そもそも辞書なんだからキーを使って引け
ばよい……
- 4.
- 5.
Q. この赤黒木 (10要素)を全走査するのに
必要な dereference の回数は?
出典: Wikipedia(ja) Red-black tree example.svg
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
A. 16 回
参考:
15 要素 25回
31 要素 57回
出典: Wikipedia(ja) Red-black tree example.svg
- 17.
- 18.
選ぶのがめんどくさい
unordered_map
全走査したい
boost::flat_map
並び順が安定しててほしい
boost::flat_map
任意の外部入力がキーになる可能性がある
boost::flat_map
- 19.
基本的には使わない
必要になるのは……
• ハッシュ関数が定義できない、かつ、要素のコ
ピーが非常に遅い場合
• 途中で要素の追加削除が発生する全走査をしたい
場合
• std::map を受け取る外部ライブラリを使う場合
要らないですね
- 20.
2重探索をしない
• find insert は NG
begin を避ける
• 必ずキーアクセスを使う
- 21.
こんなコードはNG
constauto ite = m.find(k);
if (ite == m.end()) {
return *m.insert(
std::make_pair(
k,
make_new_value(params...)
);
);
} else {
return *ite;
}
- 22.
ここで探索して
こんなコードはNG
constauto ite = m.find(k);
if (ite == m.end()) { ここでも探索している
return *m.insert(
std::make_pair( しかも値を2回コピーしている
k,
make_new_value(params...)
);
);
} else {
return *ite;
}
- 23.
lower_bound を使う
const auto ite = m.lower_bound(k);
if (ite == m.end() || ite->first != k) {
return *m.emplace_hint(
ite,
std::piecewise_construct,
std::forward_as_tuple(k),
std::forward_as_tuple(params...)
);
} else {
return *ite;
}
- 24.
探索は1回
lower_bound を使う
const auto ite = m.lower_bound(k);
if (ite == m.end() || ite->first != k) {
return *m.emplace_hint( (ヒントが正しければ)
ite, 挿入は償却定数時間
std::piecewise_construct,
std::forward_as_tuple(k),
std::forward_as_tuple(params...)
);
} else { direct initialization で
return *ite; 無駄なコピーを回避
}
- 25.
例:こんなデータを map に入れたいとき
struct item_instance: boost::noncopyable {
item_uid_t uid;
item_category_t category;
values...;
};
- 26.
安直にこういう map にすると……
std::map<
item_uid_t,
std::shared_ptr<item_instance>
> items;
- 27.
- 28.
- 29.
結局同じ
const autof = [](
const std::shared_ptr<item_instance> &p
) {
return p->category == item_category::weapon;
};
return std::vector<std::shared_ptr<item_instance>>(
boost::make_filter_iterator(
f, items.begin(), items.end()),
boost::make_filter_iterator(
f, items.end(), items.end())
);
- 30.
副キー主キーへの map を作る
std::map<
item_uid_t,
std::shared_ptr<item_instance>
> items;
std::multimap<
item_category,
item_uid_t
> items_by_category;
- 31.
「master_id からも引きたい!」
std::multimap<
item_master_id_t,
item_uid_t
> items_by_master;
これを items を操作しているすべての
場所で更新するように変更しないとい
けない!
- 32.
どうにもなりません
ならまだマシ
boost::flat_map
根本的な解決には……
• データ設計を変更するか、
• boost::multi_index を使うしかない
- 33.
- 34.
- 35.
ハッシュの衝突を意図的に大量に発生させ
る攻撃手法
キャラクター名をキーにする場合など
どの実装を使っているか推測できれば攻撃
自体は容易
• この Web サービスは PHP だから……
• ゲームサーバなんてどうせ C++ だろうし……
最近の実装ではライブラリ側で対策されて
いるので通用しない
- 36.
- 37.
std::map
• 赤黒木
std::unordered_map
• 普通のハッシュマップ
boost::flat_map
• ソート済み配列
- 38.
- 39.
a.k.a.
stdext::hash_map
辞書が必要ならとりあえずこれで
• ○ほとんどの操作が ave. O(1)
• ×最悪ケースで O(N)
• ×rehash が発生するとスパイク状の性能劣化
• △最適なハッシュ関数を定義するのが難しい
• ×非順序
- 40.
推しmap
中身はただの vector なので……
• ○走査・参照が速い
• ○省メモリ
• ×追加・削除が遅い (但しおよそ N>100 の場合)
• ×イテレータの安定性が無い
要素数が少ない場合は何も考えずに
boost::flat_map を使ってよい
- 41.