Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Immutable List Gem
2014/07/29 KLab 社内勉強会 ALM
細田 翔 (@gam0022)
自己紹介
細田 翔
筑波大学情報学群情報科学類 B4
- 非数値処理アルゴリズム研究室
15卒 KLab内定者
Twitter: @gam0022
http://gam0022.net/
2
話す内容
関数型スタイルでのクイックソートを高速化した話(Ruby)
3
クイックソート
念のためにおさらい
クイックソートの基本的な考え
- データを軸要素(ピボット)より
大きい要素・小さい要素で分割
することを再帰的に繰り返して
ソートを行なう
4
http://www.ics.kagoshima-u.ac.j...
Rubyでクイックソート
手続き型スタイルで実装した場合
特徴
1. コードが長い

(tempなどの変数が必要)
2. 昇順降順の切り替えに2箇所の変更
3. 動作が追いにくい
5
OCamlでクイックソート
OCaml (関数型言語)による実装
特徴
1. 5行で書ける!
2. 昇順降順の切り替えは1箇所の変更
3. 動作が追いやすい
6
Ruby vs OCaml
Ruby vs OCaml
- OCaml の圧倒的な勝利
Ruby でも OCaml のよう
なクイックソートを書きたい!
7
Ruby OCaml
行数 29 5
昇順降順の
変更箇所
2 1
可読性 △ ○
Ruby でクイックソート その2
OCaml Ruby
左: OCamlの5行のコードを List.partition を使わないで再実装
右: 左のコードを Ruby に移植したコード
Ruby でも関数型スタイルにプログラミングできた!
8
だが待って欲しい!
Ruby でクイックソートその2
このコードは確かに動作する
問題点
- Array#+ や Array#drop は非破
壊的メソッド
- Array のインスタンスを大量に生成
- Array を何度もコピー
10
処理コストが大きい!
データ構造を見直す
関数型スタイルのプログラミングには、Array(配列)は適さない
データ構造から見なおしてみる
(Immutable) Singly Linked List が最適
- イミュータブルな単方向連結リスト
- OCaml や ...
Immutable Singly Linked List を実装
普通に Ruby で実装してもネタとして面白くない
Array は組み込みクラスであり、C言語で実装されているので、
普通にRubyで実装してもパフォーマンス的にも勝ち目がない
...
Ruby の C拡張
C拡張
- C言語で書いたコードをリンクして Ruby から利用する仕組み
部分的な処理の高速化・ラッパーライブラリなどに使われる
例:C拡張を利用した gem
- スクレイピングライブラリの nokogiri
- SQl...
ImmutableList の実装
クラス名は ImmutableList
struct immutable_list の定義 (Cの構造体をラップ)
15
ImmutableList の実装
OCaml を意識したメソッドを実装
- cons
- head, tail
- rev_append, rev, append
- length
- nth
- inspect
16
ImmutableList の実装
cons (先頭への要素追加) の定義
17
ImmutableList の実装
全部で200行くらいで実装できた
罠が多くて苦労した
- 明示的にオブジェクトをmarkしないと GC で勝手にオブジェ
クトが開放されて SEGV が発生したりとハマりどころが多い
- Ruby 処理系の勉...
Ruby でクイックソート その3
ImmutableList を使用して再実装
19
Ruby でクイックソート 考察
全く同じ処理
クラスを置き換えただけ
性能に違いが出るか?
20
Array ImmutableList
Array ImmutableList
first head
drop(1) tail
[i]+a a....
ベンチマーク
データの長さn と 処理時間(CPU時間) の関係を調査
ソートデータ: 重複のないランダムなデータを使用
最新の Ruby 2.1.2 を使用
21
結果
22
リストの長さのクイックソートの実行時間
実行時間[sec]
0
0.1
0.2
0.3
0.4
リストの長さ[個]
0 2000 4000 6000 8000
Array ImmutableList
リストの長さに比例して、Immu...
まとめ
処理によっては、再帰を用いた関数型スタイルでプログラミン
グすることで、シンプルに実装できる場合がある
パフォーマンス的には、Ruby の Array は関数型スタイルには
適していない
C拡張として実装した ImmutableList...
RubyGems に公開中
RubyGems は Ruby ライブラリの管理システム
immutable_list の名前で登録済みなので、コマンド一発で導入可能
24
ご静聴ありがとうございました
おまけ
本当にC拡張で作った意味があったので疑問だったので、Ruby
でも同じ機能を持つクラスを実装した
ソースコードはC実装の1/3くらいになった(Rubyの生産性す
ごい)
次のベンチマークをとった
- 先ほどのクイックソート
- 単純な連...
ImmutableListのRuby実装と比較
Ruby で実装した ImmutableList(Ruby)
手続き型スタイルのクイックソート Procedural
27
リストの長さとクイックソートの実行時間
実行時間[sec]
0
0.1
...
ImmutableListのRuby実装と比較
連結の回数と実行時間(対数グラフ)
実行時間[sec]
0.01
0.1
1
10
100
連結回数[回]
1000 10000 100000
Array ImmutableList
Immuta...
ImmutableListのRuby実装と比較
C拡張版の方が高速で良かった
でも、思ったよりは変わらなくて残念(́・ω・`)
関数型スタイルは手続き型スタイルよりすごく遅い
29
Immutable List が Array より

メモリの消費が少ない説明
Arrayの連結
C = A+B を行なった時、AとBの内容を全てコピーする
1 2 3 4 5 6 7 8+
A B
1 2 3 4 5 6 7 8
A B
1 2 3 4 5 6 7 8
C
Immutable Singly Linked List の連結
C = A+B を行なった時、Bとの差分だけがコピーされる
1 2 3 4 5 6 7 8+
A B
1 2 3
A
1 2 3
C
4 5 6 7 8
B
head と tail
次の操作は参照を返すだけなので、とても高速
- head: 先頭の要素の取り出し Array#first に対応
- tail: 2番目以降のリストの取り出し Array#drop に対応
33
1 2 3 4 5 6 7...
Upcoming SlideShare
Loading in …5
×

of

Immutable List Gem (KLab ALM版) Slide 1 Immutable List Gem (KLab ALM版) Slide 2 Immutable List Gem (KLab ALM版) Slide 3 Immutable List Gem (KLab ALM版) Slide 4 Immutable List Gem (KLab ALM版) Slide 5 Immutable List Gem (KLab ALM版) Slide 6 Immutable List Gem (KLab ALM版) Slide 7 Immutable List Gem (KLab ALM版) Slide 8 Immutable List Gem (KLab ALM版) Slide 9 Immutable List Gem (KLab ALM版) Slide 10 Immutable List Gem (KLab ALM版) Slide 11 Immutable List Gem (KLab ALM版) Slide 12 Immutable List Gem (KLab ALM版) Slide 13 Immutable List Gem (KLab ALM版) Slide 14 Immutable List Gem (KLab ALM版) Slide 15 Immutable List Gem (KLab ALM版) Slide 16 Immutable List Gem (KLab ALM版) Slide 17 Immutable List Gem (KLab ALM版) Slide 18 Immutable List Gem (KLab ALM版) Slide 19 Immutable List Gem (KLab ALM版) Slide 20 Immutable List Gem (KLab ALM版) Slide 21 Immutable List Gem (KLab ALM版) Slide 22 Immutable List Gem (KLab ALM版) Slide 23 Immutable List Gem (KLab ALM版) Slide 24 Immutable List Gem (KLab ALM版) Slide 25 Immutable List Gem (KLab ALM版) Slide 26 Immutable List Gem (KLab ALM版) Slide 27 Immutable List Gem (KLab ALM版) Slide 28 Immutable List Gem (KLab ALM版) Slide 29 Immutable List Gem (KLab ALM版) Slide 30 Immutable List Gem (KLab ALM版) Slide 31 Immutable List Gem (KLab ALM版) Slide 32 Immutable List Gem (KLab ALM版) Slide 33
Upcoming SlideShare
シェーダだけで世界を創る!three.jsによるレイマーチング
Next
Download to read offline and view in fullscreen.

4 Likes

Share

Download to read offline

Immutable List Gem (KLab ALM版)

Download to read offline

関数型スタイルでのクイックソートを高速化した話(Ruby)です。KLab ALM 2014/07/29 で発表しました。

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Immutable List Gem (KLab ALM版)

  1. 1. Immutable List Gem 2014/07/29 KLab 社内勉強会 ALM 細田 翔 (@gam0022)
  2. 2. 自己紹介 細田 翔 筑波大学情報学群情報科学類 B4 - 非数値処理アルゴリズム研究室 15卒 KLab内定者 Twitter: @gam0022 http://gam0022.net/ 2
  3. 3. 話す内容 関数型スタイルでのクイックソートを高速化した話(Ruby) 3
  4. 4. クイックソート 念のためにおさらい クイックソートの基本的な考え - データを軸要素(ピボット)より 大きい要素・小さい要素で分割 することを再帰的に繰り返して ソートを行なう 4 http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/algorithm/sort-algorithm/quick-sort.html
  5. 5. Rubyでクイックソート 手続き型スタイルで実装した場合 特徴 1. コードが長い
 (tempなどの変数が必要) 2. 昇順降順の切り替えに2箇所の変更 3. 動作が追いにくい 5
  6. 6. OCamlでクイックソート OCaml (関数型言語)による実装 特徴 1. 5行で書ける! 2. 昇順降順の切り替えは1箇所の変更 3. 動作が追いやすい 6
  7. 7. Ruby vs OCaml Ruby vs OCaml - OCaml の圧倒的な勝利 Ruby でも OCaml のよう なクイックソートを書きたい! 7 Ruby OCaml 行数 29 5 昇順降順の 変更箇所 2 1 可読性 △ ○
  8. 8. Ruby でクイックソート その2 OCaml Ruby 左: OCamlの5行のコードを List.partition を使わないで再実装 右: 左のコードを Ruby に移植したコード Ruby でも関数型スタイルにプログラミングできた! 8
  9. 9. だが待って欲しい!
  10. 10. Ruby でクイックソートその2 このコードは確かに動作する 問題点 - Array#+ や Array#drop は非破 壊的メソッド - Array のインスタンスを大量に生成 - Array を何度もコピー 10
  11. 11. 処理コストが大きい!
  12. 12. データ構造を見直す 関数型スタイルのプログラミングには、Array(配列)は適さない データ構造から見なおしてみる (Immutable) Singly Linked List が最適 - イミュータブルな単方向連結リスト - OCaml や Lisp の List にも使われる 12
  13. 13. Immutable Singly Linked List を実装 普通に Ruby で実装してもネタとして面白くない Array は組み込みクラスであり、C言語で実装されているので、 普通にRubyで実装してもパフォーマンス的にも勝ち目がない 「C拡張」として、実装しよう! 13
  14. 14. Ruby の C拡張 C拡張 - C言語で書いたコードをリンクして Ruby から利用する仕組み 部分的な処理の高速化・ラッパーライブラリなどに使われる 例:C拡張を利用した gem - スクレイピングライブラリの nokogiri - SQlite3 のラッパーライブラリの sqlite3 14
  15. 15. ImmutableList の実装 クラス名は ImmutableList struct immutable_list の定義 (Cの構造体をラップ) 15
  16. 16. ImmutableList の実装 OCaml を意識したメソッドを実装 - cons - head, tail - rev_append, rev, append - length - nth - inspect 16
  17. 17. ImmutableList の実装 cons (先頭への要素追加) の定義 17
  18. 18. ImmutableList の実装 全部で200行くらいで実装できた 罠が多くて苦労した - 明示的にオブジェクトをmarkしないと GC で勝手にオブジェ クトが開放されて SEGV が発生したりとハマりどころが多い - Ruby 処理系の勉強にはすごくなった 18
  19. 19. Ruby でクイックソート その3 ImmutableList を使用して再実装 19
  20. 20. Ruby でクイックソート 考察 全く同じ処理 クラスを置き換えただけ 性能に違いが出るか? 20 Array ImmutableList Array ImmutableList first head drop(1) tail [i]+a a.cons(i)
  21. 21. ベンチマーク データの長さn と 処理時間(CPU時間) の関係を調査 ソートデータ: 重複のないランダムなデータを使用 最新の Ruby 2.1.2 を使用 21
  22. 22. 結果 22 リストの長さのクイックソートの実行時間 実行時間[sec] 0 0.1 0.2 0.3 0.4 リストの長さ[個] 0 2000 4000 6000 8000 Array ImmutableList リストの長さに比例して、ImmutableList が高速になる 最大で4.3倍の高速化!
  23. 23. まとめ 処理によっては、再帰を用いた関数型スタイルでプログラミン グすることで、シンプルに実装できる場合がある パフォーマンス的には、Ruby の Array は関数型スタイルには 適していない C拡張として実装した ImmutableList によって、関数型スタ イルでのクイックソートを高速化することができた! 23
  24. 24. RubyGems に公開中 RubyGems は Ruby ライブラリの管理システム immutable_list の名前で登録済みなので、コマンド一発で導入可能 24
  25. 25. ご静聴ありがとうございました
  26. 26. おまけ 本当にC拡張で作った意味があったので疑問だったので、Ruby でも同じ機能を持つクラスを実装した ソースコードはC実装の1/3くらいになった(Rubyの生産性す ごい) 次のベンチマークをとった - 先ほどのクイックソート - 単純な連結(append)処理 26
  27. 27. ImmutableListのRuby実装と比較 Ruby で実装した ImmutableList(Ruby) 手続き型スタイルのクイックソート Procedural 27 リストの長さとクイックソートの実行時間 実行時間[sec] 0 0.1 0.2 0.3 0.4 リストの長さ[個] 0 2000 4000 6000 8000 Array ImmutableList ImmutableList(Ruby) Procedural C拡張版の方が少し高速
  28. 28. ImmutableListのRuby実装と比較 連結の回数と実行時間(対数グラフ) 実行時間[sec] 0.01 0.1 1 10 100 連結回数[回] 1000 10000 100000 Array ImmutableList ImmutableList(Ruby) 長さ6のリストをn回連結 28
  29. 29. ImmutableListのRuby実装と比較 C拡張版の方が高速で良かった でも、思ったよりは変わらなくて残念(́・ω・`) 関数型スタイルは手続き型スタイルよりすごく遅い 29
  30. 30. Immutable List が Array より
 メモリの消費が少ない説明
  31. 31. Arrayの連結 C = A+B を行なった時、AとBの内容を全てコピーする 1 2 3 4 5 6 7 8+ A B 1 2 3 4 5 6 7 8 A B 1 2 3 4 5 6 7 8 C
  32. 32. Immutable Singly Linked List の連結 C = A+B を行なった時、Bとの差分だけがコピーされる 1 2 3 4 5 6 7 8+ A B 1 2 3 A 1 2 3 C 4 5 6 7 8 B
  33. 33. head と tail 次の操作は参照を返すだけなので、とても高速 - head: 先頭の要素の取り出し Array#first に対応 - tail: 2番目以降のリストの取り出し Array#drop に対応 33 1 2 3 4 5 6 7 8 tail head
  • takukamata

    May. 9, 2019
  • ippeinawate

    Aug. 1, 2014
  • motoshinishihira

    Jul. 30, 2014
  • dxhuy88

    Jul. 29, 2014

関数型スタイルでのクイックソートを高速化した話(Ruby)です。KLab ALM 2014/07/29 で発表しました。

Views

Total views

5,311

On Slideshare

0

From embeds

0

Number of embeds

3,176

Actions

Downloads

3

Shares

0

Comments

0

Likes

4

×