昔書いたコードを書き直す。(Simpson係数を求める)
昔書いたコードを直したくなったので直してみました。><
以前書いたコード
http://d.hatena.ne.jp/trotr/20071008#1191852704
そういえばこの頃は"if __FILE__ == $0"の意味を理解していなかった><。
変更後のコード
変更点は以下のような感じです。。
- classを作った。
- Simsonモジュールを作った。
- calcメソッドを定義したクラスを作れば、pubmedに限らずSimpson係数を求められる
- exit(-1)のような形ではなく例外をだすようにした。
- 前に作った時は例外とかよく分かってなかったような気がする。
- 一度調べた値は覚えておくことにした。
- Simsonモジュールの機能
速度の比較
"CDK2", "CDK6", "CDK3", "CDK5"で実行した時の値。
simpson.rbが以前のものでsimpson2.rbが書き直したものです。
$ time ruby1.8 simpson.rb ["CDK2+CDK6", 0.420595533498759] ["CDK2+CDK3", 0.673469387755102] ["CDK2+CDK5", 0.122] ["CDK6+CDK3", 0.183673469387755] ["CDK6+CDK5", 0.0347394540942928] ["CDK3+CDK5", 0.285714285714286] ruby1.8 simpson2.tmp.rb 0.50s user 0.09s system 7% cpu 8.379 total $ time ruby1.8 simpson2.rb CDK2+CDK6 : 0.420595533498759 CDK2+CDK3 : 0.673469387755102 CDK2+CDK5 : 0.122 CDK6+CDK3 : 0.183673469387755 CDK6+CDK5 : 0.0347394540942928 CDK3+CDK5 : 0.285714285714286 ruby1.8 simpson2.rb 0.57s user 0.05s system 12% cpu 4.978 total
早くなっている。たぶん要素の数が増えるほど差は広がると思う。
書き直したコード
#!/usr/bin/env ruby1.9 # -*- encoding: utf-8 -*- require 'open-uri' require 'rexml/document' module Simpson def initialize #puts "Simpson is included" @mem = { } # !> `&' interpreted as argument prefix @queue = [] @compound_name = proc{ |x,y| "#{x}+#{y}"} @output = proc { |name,n| puts("#{name} : #{n}")} end def count raise "count methods is not defined." end def push *elements @queue.push(*elements) end def make_combination!(queue) result = [] until queue.empty? x = queue.shift result.push *queue.map{ |y| [x,y]} end result end def run! &block calc_allcombination(@queue, &block) end def run &block calc_allcombination(@queue.dup, &block) end def calc_allcombination(queue, &block) block = @output unless block a = make_combination!(queue) a.each do |x,y| name = @compound_name[x,y] block.call(name, calc(x,y)) end end def calc x,y get(@compound_name[x,y]) / [x,y].map{ |e| get(e)}.min end def set(gene,num) raise "value is zero" if num < 0 @mem[gene] = num ; return num end def get gene @mem[gene]? @mem[gene] : set(gene,count(gene)) end public :run, :run!, :push, :calc private :count, :set, :get, :calc_allcombination end class Checker include Simpson def initialize super @base = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=" end def prepare gene url = @base + gene open(url).read end def count gene source = prepare gene doc = REXML::Document.new source doc.elements['/eSearchResult/Count'].text.to_f end private :prepare, :count end # ch = Checker.new # ch.push("CDK2", "CDK6", "CDK3", "CDK5") # ch.run! # >> CDK2+CDK6 : 0.420595533498759 # >> CDK2+CDK3 : 0.673469387755102 # >> CDK2+CDK5 : 0.122 # >> CDK6+CDK3 : 0.183673469387755 # >> CDK6+CDK5 : 0.0347394540942928 # >> CDK3+CDK5 : 0.285714285714286