SlideShare a Scribd company logo
Aiming 大阪スタジオ
エンジニア勉強会 2013-03-11

     Tomohiro Kashiwada
 std::map を for で回したことがある
 std::map::lower_bound を使わない
 map::find より map::begin をよく使う
 面倒だし std::map でも全探索する
 速度が重要だと考えているなら、今すぐ
  std::map の全走査はやめましょう
 std::list より、さらに遅い
 赤黒木で実装されているので仕方ない
 そもそも辞書なんだからキーを使って引け
  ばよい……
の典型的な内部実装
 std::map
 平衡二分木の一つ
 ほとんどの操作が O(logN)
 ただし定数係数が非常に大きい
Q. この赤黒木 (10 要素)を全走査するのに
必要な dereference の回数は?




          出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
出典: Wikipedia(ja) Red-black tree example.svg
A. 16 回
参考:
 15 要素  25回
 31 要素  57回




               出典: Wikipedia(ja) Red-black tree example.svg
 コンテナを用途によって正しく使い分ける
  ことは、どんな最適化よりも重要
 1byte のコピーを削減するよりも、用途に
  マッチしたコンテナを使うほうが効果大
 具体的にはどういう基準で選定するのか?
 選ぶのがめんどくさい
   unordered_map
 全走査したい
   boost::flat_map
 並び順が安定しててほしい
   boost::flat_map
 任意の外部入力がキーになる可能性がある
   boost::flat_map
 基本的には使わない
 必要になるのは……
 • ハッシュ関数が定義できない、かつ、要素のコ
   ピーが非常に遅い場合
 • 途中で要素の追加削除が発生する全走査をしたい
   場合
 • std::map を受け取る外部ライブラリを使う場合
 要らないですね
 2重探索をしない
  • find  insert は NG
 begin   を避ける
  • 必ずキーアクセスを使う
 こんなコードはNG
 const auto ite = m.find(k);
 if (ite == m.end()) {
   return *m.insert(
     std::make_pair(
       k,
       make_new_value(params...)
     );
   );
 } else {
   return *ite;
 }
ここで探索して
 こんなコードはNG
 const auto ite = m.find(k);
 if (ite == m.end()) {     ここでも探索している
   return *m.insert(
     std::make_pair(   しかも値を2回コピーしている
       k,
       make_new_value(params...)
     );
   );
 } else {
   return *ite;
 }
 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;
  }
探索は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;             無駄なコピーを回避
  }
 例:こんなデータを           map に入れたいとき

   struct item_instance: boost::noncopyable {
     item_uid_t         uid;
     item_category_t    category;
     values...;
   };
 安直にこういう        map にすると……

   std::map<
     item_uid_t,
     std::shared_ptr<item_instance>
   > items;
 「武器だけ列挙したい!」

std::vector<std::shared_ptr<item_instance>> ret;
std::remove_copy_if(
  items.begin(),
  items.end(),
  std::back_inserter(ret),
  [&](const std::shared_ptr<item_instance> &i) {
    return i->category != item_category::weapon;
  }
);
return ret;
 boost::filter_iterator      を使う
  • http://www.boost.org/doc/libs/1_53_0/libs/iterator/d
    oc/filter_iterator.html
 結局同じ

const auto f = [](
  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())
);
 副キー主キーへの             map を作る
std::map<
  item_uid_t,
  std::shared_ptr<item_instance>
> items;
std::multimap<
  item_category,
  item_uid_t
> items_by_category;
 「master_id    からも引きたい!」
 std::multimap<
   item_master_id_t,
   item_uid_t
 > items_by_master;

    これを items を操作しているすべての
    場所で更新するように変更しないとい
    けない!
 どうにもなりません
         ならまだマシ
 boost::flat_map
 根本的な解決には……
  • データ設計を変更するか、
  • boost::multi_index を使うしかない
 std::map   は要らない子
 「任意の外部入力がキーになる」とは?
 • hashdos
各   *map の特性の違い
 • std::map
 • std::unordered_map
 • boost::flat_map
 ハッシュの衝突を意図的に大量に発生させ
  る攻撃手法
 キャラクター名をキーにする場合など
 どの実装を使っているか推測できれば攻撃
  自体は容易
 • この Web サービスは PHP だから……
 • ゲームサーバなんてどうせ C++ だろうし……
 最近の実装ではライブラリ側で対策されて
いるので通用しない
 おググりください
 http://blog.tokumaru.org/2011/12/webdosh
 ashdos.html
 std::map
  • 赤黒木
 std::unordered_map
  • 普通のハッシュマップ
 boost::flat_map
  • ソート済み配列
 みんな知ってる
 イテレータの安定性がウリ
 • ○追加削除が発生してもイテレータは失効しない
 • ○順序付
 • ×メモリ大食い (1要素につきポインタ3個)
 • ×操作(走査)が遅い (最良で O(logN) )
 a.k.a.
     stdext::hash_map
 辞書が必要ならとりあえずこれで
  • ○ほとんどの操作が ave. O(1)
  • ×最悪ケースで O(N)
  • ×rehash が発生するとスパイク状の性能劣化
  • △最適なハッシュ関数を定義するのが難しい
  • ×非順序
 推しmap
 中身はただの   vector なので……
 • ○走査・参照が速い
 • ○省メモリ
 • ×追加・削除が遅い (但しおよそ N>100 の場合)
 • ×イテレータの安定性が無い
 要素数が少ない場合は何も考えずに
 boost::flat_map を使ってよい
 std::map   は要らない子

More Related Content

What's hot

中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだGenya Murakami
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Shiqiao Du
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!Genya Murakami
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
Ryosuke Okuta
 
TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?
Mr. Vengineer
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
信之 岩永
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
Masahiro Sakai
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
MITSUNARI Shigeo
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
Yoshifumi Kawai
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
Ryosuke839
 
3次元計測とフィルタリング
3次元計測とフィルタリング3次元計測とフィルタリング
3次元計測とフィルタリング
Norishige Fukushima
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
大樹 小倉
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計
増田 亨
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
Fixstars Corporation
 
SSII2020SS: 微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​
SSII2020SS:  微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​SSII2020SS:  微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​
SSII2020SS: 微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​
SSII
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
Fixstars Corporation
 

What's hot (20)

中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
CuPy解説
CuPy解説CuPy解説
CuPy解説
 
TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
3次元計測とフィルタリング
3次元計測とフィルタリング3次元計測とフィルタリング
3次元計測とフィルタリング
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
SSII2020SS: 微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​
SSII2020SS:  微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​SSII2020SS:  微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​
SSII2020SS: 微分可能レンダリングの最新動向 〜「見比べる」ことによる3次元理解 〜​
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
 

Similar to Map

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編egtra
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
時響 逢坂
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
necocen
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweightgintenlabo
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database Analytics
Kohei KaiGai
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11えぴ 福田
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
Tatsuki SHIMIZU
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
Boost tour 1_44_0
Boost tour 1_44_0Boost tour 1_44_0
Boost tour 1_44_0
Akira Takahashi
 
C++ lecture-1
C++ lecture-1C++ lecture-1
C++ lecture-1sunaemon
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
yak1ex
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
Hiro H.
 
Boost.B-tree introduction
Boost.B-tree introductionBoost.B-tree introduction
Boost.B-tree introduction
Takayuki Goto
 

Similar to Map (20)

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweight
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database Analytics
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
Boost tour 1_44_0
Boost tour 1_44_0Boost tour 1_44_0
Boost tour 1_44_0
 
C++ lecture-1
C++ lecture-1C++ lecture-1
C++ lecture-1
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 
Boost.B-tree introduction
Boost.B-tree introductionBoost.B-tree introduction
Boost.B-tree introduction
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 

Map