若いプログラマが問題を解くと
Upcoming SlideShare
Loading in...5
×
 

若いプログラマが問題を解くと

on

  • 935 views

Code HAIKU 2012の発表資料です。

Code HAIKU 2012の発表資料です。
http://atnd.org/events/33788

Statistics

Views

Total Views
935
Views on SlideShare
717
Embed Views
218

Actions

Likes
0
Downloads
0
Comments
0

5 Embeds 218

http://developer.cybozu.co.jp 184
http://feeds.feedburner.com 25
http://s.deeeki.com 5
http://developer-test.cybozu.co.jp 3
https://cybozulive.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Map('x -> "Desknet's NEO", 'x -> "Cybozu Office 9"). get('x). map( _ + " is the great").getOrElse("What is"). union(" collaboration software")

若いプログラマが問題を解くと 若いプログラマが問題を解くと Presentation Transcript

  • 若いプログラマが問題を解く と 村崎 大輔 daisuke-murasaki@cybozu.co.jp 2012-12-16
  • Outline• 自己紹介• 今日の一句• とある製品の検索機能について
  • 自己紹介• 村崎 大輔 (むらさき だいすけ)• サイボウズ株式会社 松山開発部• メールワイズなどの開発をしています
  • 今日の一句
  • 問題1• サイボウズ Office と、サイボウズ ガルー ン どちらが素晴らしいグループウェアか
  • Scalaで聞いてみよう
  • 問題を記述するMap(x -> "Cybozu Garoon", x -> "Cybozu Office 9"). get(x). map( _ + " is the great"). getOrElse("What is"). union(" collaboration software")
  • 回答
  • 先の問題のポイント サイボウズ Office 9 はすばらしいグループウェア ではなく、
  • プログラミング言語やライブラリの設 計が 書かれるコードのセンスを左右する
  • 問題2• 対応表にキーと値が入っている(文字 列) – 対応表:マップ、ハッシュ表、連想配列• 何かキーが与えられたとき、 – 対応表に値が入っていればその値 – 値が見つからなければ "not found" を表示したい
  • C + GLibの場合value = g_hash_table_lookup(table, key);if (value) { puts(value);} else { puts("not found");}
  • そうだ!?演算子を使おうvalue = g_hash_table_lookup(table, key);puts(value ? value : "not found");
  • 他のプログラミング言語だと どうなるか?
  • Rubyの場合value = table[key]if value puts(value)else puts("not found")end
  • ||演算子を使うvalue = table[key]puts(value || "not found")
  • A || B• C言語の場合 – Aを評価して真であれば 1 – そうでなければ、Bを評価して 真であれば 1、偽であれば 0• Rubyの場合 – Aを評価して真であれば A – そうでなければ、Bを評価して B
  • 実は、 Hash#fetch を使うとvalue = table.fetch(key, "not found")puts(value)
  • ここからが本題
  • 問題3• キーを与えて、 – 対応表に値(文字列)が入っていれば "found 値" – 値が見つからなければ "not found" を表示したい
  • C with GLib の場合value = g_hash_table_lookup(table, key);if (value) { printf("found %sn", value);} else { puts("not found");}
  • スッキリ書けない
  • Rubyだと?value = table[key]if value puts("found #{value}")else puts("not found")end
  • 式展開• 文字列式の中に、別の式を評価した結果 の値(を文字列にしたもの)を埋め込む – "1+2 = #{1+2}" → "1+2 = 3"• テンプレートエンジンでは無くては困る 機能 – サイボウズOfficeなどのかんたん系でも 使ってます(厳密には式じゃない)
  • Scalaだと?val value = table.get(key)if (value.isDefined) { println("found " + value.get)} else { println("not found")}
  • ちょっとめんどくさい?
  • value = table[key]if value puts("found #{value}")else puts("not found")endval value = table.get(key)if (value.isDefined) { println("found " + value.get)} else { println("not found")}
  • ScalaのMap• get(key) で返ってくる値は、値そのもので は なくOption型に値が入ったもの• 中に値が入っているかを調べるには value.isDefined• 中に入っている値を返すには value.get
  • まだまだ!Optionはこんなものじゃな い!
  • Option#map(f)• Optionが空でなければ、値を関数 f に与えて 評価して、その値を返す value.map("found " + _)• JavaScriptで書くとすれば value.map(function(v) { return "found " + v });
  • 使ってみましょうval value = table.get(key)val mapped = value.map("found " + _)if (mapped.isDefined) { println(mapped.get)} else { println("not found")}
  • Option#getOrElse(v)• Optionが空でなければ、その値を返す• Optionが空であれば、v を返す
  • 使ってみましょうval value = table.get(key)val message = value.map("found " + _)println(message.getOrElse("not found"))
  • まとめちゃいましょうprintln( table.get(key). map("found " + _). getOrElse("not found"))
  • せんせい!Perl Rubyでもできますか?!
  • できないことはないvalue = [table[key]].compactmessage = value.map {|v| “found #{v}”}puts(message.first || "not found")
  • ちょっと無理がある
  • それって○○でも(ry
  • それって○○でも(ry• Haskell – Maybe• C++ – Boost.Optional など• C# (.NET) – Nullable• SQL – NULL
  • ここまでのまとめ• 同じことをするために必要なコードは、 プログラミング言語によってまちまち• 同じプログラミング言語でも、 使い手の知識と思考によってコードが変 わる• どんなコードが美しいかは人それぞれ
  • 最初のCodeを もう一度
  • サイボウズOfficeはすばらしい (ryMap(x -> “Cybozu Garoon", x -> "Cybozu Office 9"). get(x). map( _ + " is the great"). getOrElse("What is"). union(" collaboration software")
  • とある製品の検索機能
  • とある製品
  • 遅い…
  • なぜメールワイズの検索は遅いの か• 対象のメール「全て」をデータベースか ら読み 込み、条件判定する• 対象のメールが多くなると、データベー スから読み込む時間がネックになる
  • 読み込み≒コピーの繰り返し• ディスクからOSにデータをコピー• OSからDB (SQLite) のバッファにコピー• 呼び出し元が確保したバッファにコピー• バッファの中身 (BLOB) をデシリアライズして 読み込まれたオブジェクトが復元される(コ ピー)
  • コピーを減らそう• いったん読み込んだオブジェクトを、次 に必要になったときに使い回す – 一つのプロセス単位ではやっている• これをプロセスを越えて共有する• コピーが減る
  • Boost.Interprocess• プロセス間の通信などを提供するライブラリ• Memory-mapped files – ファイルの中身をプロセスのメモリ空間にマップ する – ファイルが同じであれば、別のプロセスでも同じ メモリ内容が見える• Relative pointers – マップされたファイルの場所を指すポインタ – マップされる場所はプロセスごとに違うが、そこ をうまく変換してくれる
  • Boost.Interprocess• マップされたメモリの上に、STL風なコン テナを作ることができる• 後でリクエストを処理するときも、マッ プした コンテナには前の内容が残っている
  • とりあえずやってみた• インターンに来ていた郭さんにやってみ てもらいました(右から2番目)
  • とりあえずやってみた• デシリアライズ前のBLOBを、メモリマッ プされたmapコンテナに入れる – コンテナにあれば、コピー不要でデシリアラ イズできる• サイボウズOfficeのカスタムアプリを対象 に、検索時間を計測 – 10~20%の性能向上
  • おお、メール検索も 速くなりそう?
  • ちょっとまった!
  • ひょっとして• メールの全てを読み込む必要はない?• メールに現れる単語を全て抜き出して、 単語 → メールの対応表を作っておけばいいのでは?
  • 転置インデックス (inverted index)• 全文検索システムで使われるデータ構造• レコード単位転置インデックス (record level) – (単語)→(単語を含む文章)すべてのリス ト• 単語単位転置インデックス (word level) – (単語)→(単語を含む文章, 出現位置)のリ スト
  • 全文検索システム• Namazu• Apache Solr• Senna• Hyper Estraier
  • 後半のまとめ• プログラムが遅い原因はいくつもある が、 無駄なコピーをしていることがよくある• 効率を求めるなら、無駄なコピーを減ら しましょう• それよりも、データ構造とアルゴリズム が大事
  • まとめ• よいプログラミング言語• よいデータ構造• よいアルゴリズム• よいライブラリ
  • ご清聴ありがとうございまし た