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

Like this? Share it with your network

Share

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

  • 1,078 views
Uploaded on

Code HAIKU 2012の発表資料です。 ...

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,078
On Slideshare
860
From Embeds
218
Number of Embeds
5

Actions

Shares
Downloads
0
Comments
0
Likes
0

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

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • Map('x -> "Desknet's NEO", 'x -> "Cybozu Office 9"). get('x). map( _ + " is the great").getOrElse("What is"). union(" collaboration software")

Transcript

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