JavaOne Tokyo JVM言語BOF ベンチマーク JRuby

1,940 views

Published on

JavaOne Tokyo 2012 JVM言語BOF プログラミング大会のベンチマークテーマ、JRuby発表。

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,940
On SlideShare
0
From Embeds
0
Number of Embeds
42
Actions
Shares
0
Downloads
5
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

JavaOne Tokyo JVM言語BOF ベンチマーク JRuby

  1. 1. JVM言語BoF プログラミングテーマ: 赤黒木ベンチマーク (JRuby担当) 日本JRubyユーザ会 中村浩士 @nahi nahi@ruby-lang.org https://github.com/nahi
  2. 2. 赤黒木ベンチマークのポイントJVM言語 × ロジックヘビーなプログラム 速度性能? コードの読み易さ?赤黒木は最近雑誌で紹介され、馴染みがあったGroovy、Scala、JRubyで比較 さらにJava、Groovy++、CRubyも
  3. 3. 赤黒木とはデータ構造の一種: 平衡二分木(バランス木)他の平衡二分木に比べ「ほどほど」のバランスデータ追加・削除後のバランス調整が楽 D B B E A D A C F C E 赤黒木 F AVL木
  4. 4. レギュレーション: 連想配列RBTreeMap詳細: http://bit.ly/RedBlackTreeBenchmarkRBTreeMapは以下のAPIを持つ。 put(String key, String value) => Object keyに対してvalueを結びつける。keyにはStringの 同値性、順序性を期待できるものとする。 get(String key) => String keyに対して割り当てられている値を返す。型は各言語におけるString相当の型を扱えればよい。マルチスレッドからアクセスされた場合の挙動は未定義。
  5. 5. レギュレーション: ベンチマーク取得方法RBTreeMapをインスタンス化する。用意したファイルを開き、全てを読み終わるまで以下を繰り返す。 ファイルから1行読み込み、key、value文字列を取り出す。 RBTreeMap#put(key, value)を呼ぶ。再度同じファイルを開き、全てを読み終わるまで以下を繰り返す。 ファイルから1行読み込み、key、value文字列を取り出す。 RBTreeMap#get(key)がvalueと一致することを確認する。上記全体の経過時間を5回計測し、中間3値の平均を取る。
  6. 6. 入力データ 改行"n"、区切り","、エスケープなし 簡易CSV。key、value、木の高さの3列。aahenbi|jtbi,aahenbi|jtbi,1 ---aabpta||_s`f,aabpta||_s`f,1aaosi^t`sgd`,aaosi^t`sgd`,2 key,value,1[n]aakzh_nisbdi,aakzh_nisbdi,2aamppbpz|b|l,aamppbpz|b|l,2 key2,value2,1[n]aaleu_dhypqh,aaleu_dhypqh,2 ...aadlx`{tlvqs,aadlx`{tlvqs,2aabta__zuda|,aabta__zuda|,3 keyn,valuen,11[n][EOF]aaiga^hhtvh`,aaiga^hhtvh`,3aacczbs^kgfl,aacczbs^kgfl,3 ----aacnpac_luj^,aacnpac_luj^,3aakre^v|gmpy,aakre^v|gmpy,3aamfb`_we|ap,aamfb`_we|ap,3aaexv`mwfvyw,aaexv`mwfvyw,3aaalj^ufcaza,aaalj^ufcaza,3aaccnb_jxhhn,aaccnb_jxhhn,3aagwmb`e^suk,aagwmb`e^suk,3 実際に利用したデータはaafxpbwypsye,aafxpbwypsye,3 key==value、またkeyのaakjlbqzvgpv,aakjlbqzvgpv,4... hashCodeが全て同じ値。
  7. 7. ベンチマーク環境CPU: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz × 4Memory: 2.25GBOS: Ubuntu 11.10 64bit(VMware workstationで動作、ホストはWindows 7 64bit)Java: Java SE 7u3 Linux x64java version "1.7.0_03"Java(TM) SE Runtime Environment (build 1.7.0_03-b04)Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixedmode)
  8. 8. JRuby版ソースコード解説 赤黒木ベンチマークhttps://github.com/nahi/javaone2012-benchmark
  9. 9. class RBTreeMap def initialize def get(key) ソースコード全体概略 def put(key, value) (全メソッド抽出) class RBTree attr_reader :key, :value 定義を含め全195行 attr_accessor :color, :left, :right def initialize(key, value) def make_as_root def empty? def red? def black? def retrieve(key) def insert(key, value) class EmptyTree < RBTree def initialize def empty? def insert(key, value) end protected def insert_rotate_left def insert_rotate_right def insert_color_flip def swap_color(other) private def rotate_left def rotate_right def color_flip endend
  10. 10. class RBTreeMap def initialize def get(key) RBTreeMapのメソッド def put(key, value) class RBTree attr_reader :key, :value attr_accessor :color, :left, :right def initialize(key, value) def make_as_root def empty? def red? def black? def retrieve(key) def insert(key, value) class EmptyTree < RBTree def initialize def empty? def insert(key, value) end protected def insert_rotate_left def insert_rotate_right def insert_color_flip def swap_color(other) private def rotate_left def rotate_right def color_flip endend
  11. 11. class RBTreeMap def initialize def get(key) def put(key, value) class RBTree attr_reader :key, :value attr_accessor :color, :left, :right RBTreeMapが内部利用 def initialize(key, value) def make_as_root するRBTreeの定義 def empty? def red? def black? def retrieve(key) def insert(key, value) class EmptyTree < RBTree def initialize def empty? def insert(key, value) end protected def insert_rotate_left def insert_rotate_right def insert_color_flip def swap_color(other) private def rotate_left def rotate_right def color_flip endend
  12. 12. class RBTreeMap def initialize def get(key) def put(key, value) class RBTree attr_reader :key, :value attr_accessor :color, :left, :right def initialize(key, value) def make_as_root def empty? def red? def black? def retrieve(key) def insert(key, value) class EmptyTree < RBTree def initialize def empty? 木の末端(葉)にある def insert(key, value) end 「空」の定義 protected def insert_rotate_left def insert_rotate_right def insert_color_flip def swap_color(other) private def rotate_left def rotate_right def color_flip endend
  13. 13. class RBTreeMap def initialize def get(key) def put(key, value) class RBTree attr_reader :key, :value attr_accessor :color, :left, :right def initialize(key, value) def make_as_root def empty? def red? def black? def retrieve(key) def insert(key, value) class EmptyTree < RBTree def initialize def empty? def insert(key, value) end protected def insert_rotate_left def insert_rotate_right def insert_color_flip protected、privateの意味 def swap_color(other) private がJavaと異なるのに注意 def rotate_left def rotate_right def color_flip endend
  14. 14. class RBTree attr_reader :key, :value attr_accessor :color, :left, :right getのみ、およびget/setの def initialize(key, value) 簡易定義 @key, @value = key, value @left = @right = EMPTY # new node is added as RED @color = :RED end def make_as_root @color = :BLACK end def empty? false end def red? @color == :RED end def black? @color == :BLACK end
  15. 15. class RBTree attr_reader :key, :value attr_accessor :color, :left, :right def initialize(key, value) @key, @value = key, value @left = @right = EMPTY # new node is added as RED @color = :RED end def make_as_root @color = :BLACK end def empty? false end メソッド名末尾に?が使える def red? @color == :RED end def black? @color == :BLACK end
  16. 16. # returns new treedef insert(key, value) case key <=> @key 挿入は再帰で実装 when -1 @left = @left.insert(key,value) when 0 @value = value when 1 @right=@right.insert(key,value) end # Rebalance of LL red-black trees insert_rotate_left. insert_rotate_right. insert_color_flipend# returns valuedef retrieve(key) ptr = self while !ptr.empty? case key <=> ptr.key when -1 ptr = ptr.left when 0 return ptr.value when 1 ptr = ptr.right end end nilend
  17. 17. # returns new treedef insert(key, value) case key <=> @key when -1 @left = @left.insert(key,value) when 0 @value = value when 1 @right=@right.insert(key,value) end # Rebalance of LL red-black trees insert_rotate_left. insert_rotate_right. insert_color_flipend# returns valuedef retrieve(key) ptr = self 参照はループで実装 while !ptr.empty? case key <=> ptr.key when -1 ptr = ptr.left when 0 return ptr.value when 1 ptr = ptr.right end end nilend
  18. 18. class EmptyTree < RBTree def initialize @value = nil @color = :BLACK end def empty? true end # returns new_root def insert(key, value) RBTree.new(key, value) 末端への挿入により木が end 大きくなる def height 0 endendprivate_constant :EmptyTreeEMPTY = EmptyTree.new.freeze
  19. 19. # Do roate_left after insert if neededdef insert_rotate_left if @left.black? and @right.red? rotate_left else self endend# Do rotate_right after insert if neededdef insert_rotate_right if @left.red? and @left.left.red? rotate_right else self end リズムよく、山の形のend 定義が連なる# Do color_flip after insert if neededdef insert_color_flip if @left.red? and @right.red? color_flip else self endenddef swap_color(other) @color, other.color = other.color, @colorend
  20. 20. # Right single rotation## b d 手続き的な木の回転...# / / # a D -> B E# / / # c E a c#def rotate_left root = @right @right = root.left root.left = self root.swap_color(root.left) rootend# Left single rotation## d b# / / # B e -> A D# / / # A c c e#def rotate_right root = @left @left = root.right root.right = self root.swap_color(root.right) rootend
  21. 21. # Right single rotation## b d# / / # a D -> B E# / / # c E a c#def rotate_left root = @right @right = root.left root.left = self root.swap_color(root.left) rootend# Left single rotation## d b 逆方向もベタ書き...# / / # B e -> A D# / / # A c c e#def rotate_right root = @left @left = root.right root.right = self root.swap_color(root.right) rootend
  22. 22. class RBTreeMap class << self alias newInstance new end def initialize @root = RBTree::EMPTY end def get(key) @root.retrieve(key) end 赤黒木(RBTree)を使った def put(key, value) 連想配列(RBTreeMap) @root = @root.insert(key, value) @root.make_as_root value end def height @root.height endend ※CRuby完全互換https://github.com/nahi/javaone2012-benchmark
  23. 23. CRubyとの比較
  24. 24. JavaのHashMapとの比較

×