SlideShare una empresa de Scribd logo
1 de 24
Descargar para leer sin conexión
JVM言語BoF プログラミング
テーマ: 赤黒木ベンチマーク
      (JRuby担当)

   日本JRubyユーザ会 中村浩士
  @nahi nahi@ruby-lang.org
  https://github.com/nahi
赤黒木ベンチマークのポイント
JVM言語 × ロジックヘビーなプログラム
  速度性能?
  コードの読み易さ?

赤黒木は最近雑誌で紹介され、馴染みがあった

Groovy、Scala、JRubyで比較
  さらにJava、Groovy++、CRubyも
赤黒木とは

データ構造の一種: 平衡二分木(バランス木)
他の平衡二分木に比べ「ほどほど」のバランス
データ追加・削除後のバランス調整が楽

         D               B

     B       E       A       D

 A       C       F       C       E

                         赤黒木         F
     AVL木
レギュレーション: 連想配列RBTreeMap
詳細: http://bit.ly/RedBlackTreeBenchmark

RBTreeMapは以下のAPIを持つ。
  put(String key, String value) => Object
      keyに対してvalueを結びつける。keyにはStringの
      同値性、順序性を期待できるものとする。
  get(String key) => String
      keyに対して割り当てられている値を返す。

型は各言語におけるString相当の型を扱えればよい。
マルチスレッドからアクセスされた場合の挙動は未定義。
レギュレーション: ベンチマーク取得方法
RBTreeMapをインスタンス化する。

用意したファイルを開き、全てを読み終わるまで以下を繰り返す。
  ファイルから1行読み込み、key、value文字列を取り出す。
  RBTreeMap#put(key, value)を呼ぶ。

再度同じファイルを開き、全てを読み終わるまで以下を繰り返す。
  ファイルから1行読み込み、key、value文字列を取り出す。
  RBTreeMap#get(key)がvalueと一致することを確認する。

上記全体の経過時間を5回計測し、中間3値の平均を取る。
入力データ                         改行"n"、区切り","、エスケープなし
                              簡易CSV。key、value、木の高さの3列。
aahenbi|jtbi,aahenbi|jtbi,1   ---
aabpta||_s`f,aabpta||_s`f,1
aaosi^t`sgd`,aaosi^t`sgd`,2   key,value,1[n]
aakzh_nisbdi,aakzh_nisbdi,2
aamppbpz|b|l,aamppbpz|b|l,2
                              key2,value2,1[n]
aaleu_dhypqh,aaleu_dhypqh,2   ...
aadlx`{tlvqs,aadlx`{tlvqs,2
aabta__zuda|,aabta__zuda|,3   keyn,valuen,11[n][EOF]
aaiga^hhtvh`,aaiga^hhtvh`,3
aacczbs^kgfl,aacczbs^kgfl,3
                              ----
aacnpac_luj^,aacnpac_luj^,3
aakre^v|gmpy,aakre^v|gmpy,3
aamfb`_we|ap,aamfb`_we|ap,3
aaexv`mwfvyw,aaexv`mwfvyw,3
aaalj^ufcaza,aaalj^ufcaza,3
aaccnb_jxhhn,aaccnb_jxhhn,3
aagwmb`e^suk,aagwmb`e^suk,3
                                    実際に利用したデータは
aafxpbwypsye,aafxpbwypsye,3         key==value、またkeyの
aakjlbqzvgpv,aakjlbqzvgpv,4
...                                 hashCodeが全て同じ値。
ベンチマーク環境
CPU: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz × 4
Memory: 2.25GB
OS: Ubuntu 11.10 64bit
(VMware workstationで動作、ホストはWindows 7 64bit)

Java: Java SE 7u3 Linux x64
java 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, mixed
mode)
JRuby版ソースコード解説
             赤黒木ベンチマーク


https://github.com/nahi/javaone2012-benchmark
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
  end
end
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
  end
end
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
  end
end
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
  end
end
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
  end
end
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
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
# returns new tree
def 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_flip
end

# returns value
def 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
  nil
end
# returns new tree
def 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_flip
end

# returns value
def 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
  nil
end
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
  end
end
private_constant :EmptyTree
EMPTY = EmptyTree.new.freeze
# Do roate_left after insert if needed
def insert_rotate_left
  if @left.black? and @right.red?
    rotate_left
  else
    self
  end
end

# Do rotate_right after insert if needed
def insert_rotate_right
  if @left.red? and @left.left.red?
    rotate_right
  else
    self
  end                                         リズムよく、山の形の
end                                           定義が連なる
# Do color_flip after insert if needed
def insert_color_flip
  if @left.red? and @right.red?
    color_flip
  else
    self
  end
end

def swap_color(other)
  @color, other.color = other.color, @color
end
# 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)
  root
end

# 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)
  root
end
# 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)
  root
end

# 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)
  root
end
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
  end
end
                                        ※CRuby完全互換

https://github.com/nahi/javaone2012-benchmark
CRubyとの比較
JavaのHashMapとの比較

Más contenido relacionado

La actualidad más candente

F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
Parsing Left Recursive PEG
Parsing Left Recursive PEGParsing Left Recursive PEG
Parsing Left Recursive PEGTakayuki Goto
 
PHP基本的関数QUIZ
PHP基本的関数QUIZPHP基本的関数QUIZ
PHP基本的関数QUIZWataru Terada
 
【簡単テキストマイニング】歌詞から作品世界の魅力を探る
【簡単テキストマイニング】歌詞から作品世界の魅力を探る【簡単テキストマイニング】歌詞から作品世界の魅力を探る
【簡単テキストマイニング】歌詞から作品世界の魅力を探るShow T
 
Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]yak1ex
 
すごいHaskell読書会#10
すごいHaskell読書会#10すごいHaskell読書会#10
すごいHaskell読書会#10Shin Ise
 
C言語の宣言読み方講座
C言語の宣言読み方講座C言語の宣言読み方講座
C言語の宣言読み方講座tetra_cat
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールNobuhisa Koizumi
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
201906 のの会@関数Talk 13th
201906  のの会@関数Talk 13th201906  のの会@関数Talk 13th
201906 のの会@関数Talk 13thSatoru Abe
 
PHP classの教室
PHP classの教室PHP classの教室
PHP classの教室Yusuke Ando
 
Ocaml lecture slides 01 at axsh
Ocaml lecture slides 01 at axshOcaml lecture slides 01 at axsh
Ocaml lecture slides 01 at axshTomofumi Hayashi
 
俺のフックがこんなに簡単なわけがない。
俺のフックがこんなに簡単なわけがない。俺のフックがこんなに簡単なわけがない。
俺のフックがこんなに簡単なわけがない。Hishikawa Takuro
 
Perl 6 Object-Oliented Programming
Perl 6 Object-Oliented ProgrammingPerl 6 Object-Oliented Programming
Perl 6 Object-Oliented Programmingrisou
 
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bashJun Nogata
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Functional Pearl + Brainfuck
Functional Pearl + BrainfuckFunctional Pearl + Brainfuck
Functional Pearl + BrainfuckEita Sugimoto
 
詳説ぺちぺち
詳説ぺちぺち詳説ぺちぺち
詳説ぺちぺちdo_aki
 

La actualidad más candente (20)

F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
Parsing Left Recursive PEG
Parsing Left Recursive PEGParsing Left Recursive PEG
Parsing Left Recursive PEG
 
PHP基本的関数QUIZ
PHP基本的関数QUIZPHP基本的関数QUIZ
PHP基本的関数QUIZ
 
【簡単テキストマイニング】歌詞から作品世界の魅力を探る
【簡単テキストマイニング】歌詞から作品世界の魅力を探る【簡単テキストマイニング】歌詞から作品世界の魅力を探る
【簡単テキストマイニング】歌詞から作品世界の魅力を探る
 
Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]
 
すごいHaskell読書会#10
すごいHaskell読書会#10すごいHaskell読書会#10
すごいHaskell読書会#10
 
C言語の宣言読み方講座
C言語の宣言読み方講座C言語の宣言読み方講座
C言語の宣言読み方講座
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
201906 のの会@関数Talk 13th
201906  のの会@関数Talk 13th201906  のの会@関数Talk 13th
201906 のの会@関数Talk 13th
 
PHP classの教室
PHP classの教室PHP classの教室
PHP classの教室
 
Ocaml lecture slides 01 at axsh
Ocaml lecture slides 01 at axshOcaml lecture slides 01 at axsh
Ocaml lecture slides 01 at axsh
 
Find(1)
Find(1)Find(1)
Find(1)
 
俺のフックがこんなに簡単なわけがない。
俺のフックがこんなに簡単なわけがない。俺のフックがこんなに簡単なわけがない。
俺のフックがこんなに簡単なわけがない。
 
Perl 6 Object-Oliented Programming
Perl 6 Object-Oliented ProgrammingPerl 6 Object-Oliented Programming
Perl 6 Object-Oliented Programming
 
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
姫路IT系勉強会 Vol.11 第0回L-1グランプリ bash
 
PHP7を魔改造した話
PHP7を魔改造した話PHP7を魔改造した話
PHP7を魔改造した話
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Functional Pearl + Brainfuck
Functional Pearl + BrainfuckFunctional Pearl + Brainfuck
Functional Pearl + Brainfuck
 
詳説ぺちぺち
詳説ぺちぺち詳説ぺちぺち
詳説ぺちぺち
 

Destacado

Practica de bioquimica. pilar
Practica de bioquimica. pilarPractica de bioquimica. pilar
Practica de bioquimica. pilarPilarcita Linda
 
DIALLOG.com.pk. MARCOM (Eng.)
DIALLOG.com.pk. MARCOM (Eng.)DIALLOG.com.pk. MARCOM (Eng.)
DIALLOG.com.pk. MARCOM (Eng.)Dimitri Bushik
 
Declaracao universal direitos_humanos
Declaracao universal direitos_humanosDeclaracao universal direitos_humanos
Declaracao universal direitos_humanosmagdamesquita
 
Bloco1 parte3 umarf
Bloco1 parte3 umarfBloco1 parte3 umarf
Bloco1 parte3 umarfDafmet Ufpel
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsLinkedIn
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerLuminary Labs
 

Destacado (6)

Practica de bioquimica. pilar
Practica de bioquimica. pilarPractica de bioquimica. pilar
Practica de bioquimica. pilar
 
DIALLOG.com.pk. MARCOM (Eng.)
DIALLOG.com.pk. MARCOM (Eng.)DIALLOG.com.pk. MARCOM (Eng.)
DIALLOG.com.pk. MARCOM (Eng.)
 
Declaracao universal direitos_humanos
Declaracao universal direitos_humanosDeclaracao universal direitos_humanos
Declaracao universal direitos_humanos
 
Bloco1 parte3 umarf
Bloco1 parte3 umarfBloco1 parte3 umarf
Bloco1 parte3 umarf
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving Cars
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI Explainer
 

Más de Hiroshi Nakamura

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSHiroshi Nakamura
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in rubyHiroshi Nakamura
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasHiroshi Nakamura
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparisonHiroshi Nakamura
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyHiroshi Nakamura
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)Hiroshi Nakamura
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方Hiroshi Nakamura
 

Más de Hiroshi Nakamura (10)

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSS
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in ruby
 
Embulk 20150411
Embulk 20150411Embulk 20150411
Embulk 20150411
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvas
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)
 
現実世界のJRuby
現実世界のJRuby現実世界のJRuby
現実世界のJRuby
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方
 
HSM超入門講座
HSM超入門講座HSM超入門講座
HSM超入門講座
 

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

  • 1. JVM言語BoF プログラミング テーマ: 赤黒木ベンチマーク (JRuby担当) 日本JRubyユーザ会 中村浩士 @nahi nahi@ruby-lang.org https://github.com/nahi
  • 2. 赤黒木ベンチマークのポイント JVM言語 × ロジックヘビーなプログラム 速度性能? コードの読み易さ? 赤黒木は最近雑誌で紹介され、馴染みがあった Groovy、Scala、JRubyで比較 さらにJava、Groovy++、CRubyも
  • 4. レギュレーション: 連想配列RBTreeMap 詳細: http://bit.ly/RedBlackTreeBenchmark RBTreeMapは以下のAPIを持つ。 put(String key, String value) => Object keyに対してvalueを結びつける。keyにはStringの 同値性、順序性を期待できるものとする。 get(String key) => String keyに対して割り当てられている値を返す。 型は各言語におけるString相当の型を扱えればよい。 マルチスレッドからアクセスされた場合の挙動は未定義。
  • 5. レギュレーション: ベンチマーク取得方法 RBTreeMapをインスタンス化する。 用意したファイルを開き、全てを読み終わるまで以下を繰り返す。 ファイルから1行読み込み、key、value文字列を取り出す。 RBTreeMap#put(key, value)を呼ぶ。 再度同じファイルを開き、全てを読み終わるまで以下を繰り返す。 ファイルから1行読み込み、key、value文字列を取り出す。 RBTreeMap#get(key)がvalueと一致することを確認する。 上記全体の経過時間を5回計測し、中間3値の平均を取る。
  • 6. 入力データ 改行"n"、区切り","、エスケープなし 簡易CSV。key、value、木の高さの3列。 aahenbi|jtbi,aahenbi|jtbi,1 --- aabpta||_s`f,aabpta||_s`f,1 aaosi^t`sgd`,aaosi^t`sgd`,2 key,value,1[n] aakzh_nisbdi,aakzh_nisbdi,2 aamppbpz|b|l,aamppbpz|b|l,2 key2,value2,1[n] aaleu_dhypqh,aaleu_dhypqh,2 ... aadlx`{tlvqs,aadlx`{tlvqs,2 aabta__zuda|,aabta__zuda|,3 keyn,valuen,11[n][EOF] aaiga^hhtvh`,aaiga^hhtvh`,3 aacczbs^kgfl,aacczbs^kgfl,3 ---- aacnpac_luj^,aacnpac_luj^,3 aakre^v|gmpy,aakre^v|gmpy,3 aamfb`_we|ap,aamfb`_we|ap,3 aaexv`mwfvyw,aaexv`mwfvyw,3 aaalj^ufcaza,aaalj^ufcaza,3 aaccnb_jxhhn,aaccnb_jxhhn,3 aagwmb`e^suk,aagwmb`e^suk,3 実際に利用したデータは aafxpbwypsye,aafxpbwypsye,3 key==value、またkeyの aakjlbqzvgpv,aakjlbqzvgpv,4 ... hashCodeが全て同じ値。
  • 7. ベンチマーク環境 CPU: Intel(R) Core(TM) i5 CPU M 540 @ 2.53GHz × 4 Memory: 2.25GB OS: Ubuntu 11.10 64bit (VMware workstationで動作、ホストはWindows 7 64bit) Java: Java SE 7u3 Linux x64 java 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, mixed mode)
  • 8. JRuby版ソースコード解説 赤黒木ベンチマーク https://github.com/nahi/javaone2012-benchmark
  • 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 end end
  • 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 end end
  • 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 end end
  • 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 end end
  • 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 end end
  • 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. 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. # returns new tree def 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_flip end # returns value def 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 nil end
  • 17. # returns new tree def 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_flip end # returns value def 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 nil end
  • 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 end end private_constant :EmptyTree EMPTY = EmptyTree.new.freeze
  • 19. # Do roate_left after insert if needed def insert_rotate_left if @left.black? and @right.red? rotate_left else self end end # Do rotate_right after insert if needed def insert_rotate_right if @left.red? and @left.left.red? rotate_right else self end リズムよく、山の形の end 定義が連なる # Do color_flip after insert if needed def insert_color_flip if @left.red? and @right.red? color_flip else self end end def swap_color(other) @color, other.color = other.color, @color end
  • 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) root end # 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) root end
  • 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) root end # 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) root end
  • 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 end end ※CRuby完全互換 https://github.com/nahi/javaone2012-benchmark