よたらぼ
自分の興味の赴くままにIT技術系のネタを取りとめもなくメモっています。
Ruby言語やLinuxのネタが多いです。

September 05, 2002

[tDiary] XREAのCPU負荷が依然高いので

泣く泣くプラグインを減らしました(T_T)。

[Misc] Pocket PCって

Linuxと連動できるのかな?

[tDiary] Uconvモジュール入れ替え

前バージョンはメモリリークの可能性があったそうだ。で、それのFIX版が出たのでさっそく入れ替えた。素早い対応、感謝です>よしだむさん。


September 05, 2004

[Misc] 夏休み

ニューヨークに行って来ます。

PCは持っていきませんので1週間は連絡つきません。まぁ、向こうでインターネットカフェとかよるかもしれませんけど。

ちなみに、9/11の飛行機で帰ってきます。ニュースにならないことを祈ります(^^;)。

本日のツッコミ(全2件) [ツッコミを入れる]

lrz [have a nice trip!]

むとぽん [ありがとう。]


September 05, 2005

[Ruby] Ruby-GetText-Packageのruby標準ライブラリへの審査

まつもとさんからご返事が。喜び(&仕事疲れ?)のあまり必要なことだけ書いたところでメール送信してしまった...。読み返してみるとスゲー無愛想なメールだ。といって再び送るのもなんだし.....。とりあえず、この場で....失礼しましたm(__)m。

「Rubyっぽさ」について議論してから問題ないようでしたら取り込みましょう、ということなので、何かありましたら是非議論に参加してくださいませ。

もし、結果としてRuby本体に取り込まれなくてもきっと実のある議論になるんじゃないかと思います。

私自身、標準添付化するにあたりクリアしておきたいネタはいくつかあるので、誰からも意見が無いようならひとまず自分からネタ出ししようと思います。

#一番のネックはsetlocale()だろうな....。でもここは乗り越えないと前に進めないなぁ。

本日のツッコミ(全2件) [ツッコミを入れる]

たむら [がんがれー # 本当は見て参加すべきなんだろーけどなー]

むとう [いやいや。るびまお疲れ様です。]


September 05, 2006

[Ruby] Module.nesting

例えば、Foo::Bar::Baz というモジュールがあった場合に、[Foo::Bar::Baz, Foo::Bar, Foo]という感じに外へ外へと返してくれるメソッドはないかなぁ、と思ってリファレンスマニュアルを探したら、Module.nestingを発見。そういえば、そんなメソッドもあったなぁ、と思って試してみた・・・。んだけど、2番目の戻り値が想定外だった。同じじゃないのか。ふーむ。

$ cat test.rb
module Foo
  module Bar
    module Baz
      p Module.nesting
    end
  end
end
 
module Foo::Bar::Baz
  p Module.nesting
end
 
$ ruby test.rb
[Foo::Bar::Baz, Foo::Bar, Foo]
[Foo::Bar::Baz]
$ ruby -v
ruby 1.8.4 (2005-12-24) [i686-linux]

[Ruby] Module.nesting(2)

injectを使って、自前で実装してみた。split(/::/)とせずにREG_NESTに代入して使い回すのは高速化の第一歩だよねー(後で追記:これ、うそ。下の方で検証結果あり)。

$ cat test.rb
REG_NEST = /::/
def nesting(klass)
  klass.name.split(REG_NEST).inject([]) {|ret, v|
    if ret.size == 0
      ret << eval(v)
    else
      ret << eval("#{ret.last}::#{v}")
    end
  }.reverse
end
 
module Foo
  module Bar
    module Baz; end
  end
end
 
require 'benchmark'
Benchmark.bm(9){ |x|
  x.report("nesting"){
    10000.times{
      nesting(Foo::Bar::Baz)
      nesting(Foo::Bar)
      nesting(Foo)
    }
  }
}
$ ruby test.rb
               user     system      total        real
nesting    1.260000   0.220000   1.480000 (  1.520556)

[Ruby] Module.nesting(3)

いろいろ試してみた。injectよりeachの方が、evalよりもconst_getの方が、if文より3項演算子が速いみたい。これが最速?

$ cat test.rb
REG_NEST = /::/
def nesting(klass)
  ret = []
  klass.name.split(REG_NEST).each do |v|
    ret << ((ret.size == 0) ? eval(v) : ret.last.const_get(v))
  end
  ret.reverse
end
 
module Foo
  module Bar
    module Baz; end
  end
end
 
require 'benchmark'
Benchmark.bm(9){ |x|
  x.report("nesting"){
    10000.times{
      nesting(Foo::Bar::Baz)
      nesting(Foo::Bar)
      nesting(Foo)
    }
  }
}
$ ruby test.rb
               user     system      total        real
nesting    0.730000   0.160000   0.890000 (  0.939074)

[Ruby] Module.nesting(4)

eachよりwhileの方が速いか? reverseをしないようにしてみたらさらに高速化できた。

$ cat test.rb
REG_NEST = /::/
def nesting(klass)
  ret = []
  ary = klass.name.split(REG_NEST)
  while(v = ary.shift)
    ret.unshift(((ret.size == 0) ? eval(v) : ret[0].const_get(v)))
  end
  ret
end
 
module Foo
  module Bar
    module Baz; end
  end
end
 
require 'benchmark'
Benchmark.bm(9){ |x|
  x.report("nesting"){
    10000.times{
      nesting(Foo::Bar::Baz)
      nesting(Foo::Bar)
      nesting(Foo)
    }
  }
}
$ ruby test.rb
               user     system      total        real
nesting6   0.680000   0.070000   0.750000 (  0.773468)

もっと速い方法ある?

[Ruby] 正規表現オブジェクトを定数で持つと高速化になる?

「split(/::/)とせずにREG_NESTに代入して使い回すのは高速化の第一歩」って書いたけど、これはホントか?と思ってちょっとやってみたらほとんど関係なかった。遅くなるときすらある。そういうものか。

$ cat test3.rb
require 'benchmark'
REGEXP = /::/
Benchmark.bm(8){ |x|
  x.report("regexp1"){100000.times{"ABC::DEF".split(/::/)}}
  x.report("regexp2"){100000.times{"ABC::DEF".split(REGEXP)}}
}
 
$ ruby test3.rb
              user     system      total        real
regexp1   0.690000   0.070000   0.760000 (  0.790722)
regexp2   0.710000   0.070000   0.780000 (  0.805602)

これは勉強になった。

[Ruby] Module.nesting(5)

上の結果を受けてREG_NEST定数を使わずに埋め込みでやってみた。

$ cat test.rb
def nesting(klass)
  ret = []
  ary = klass.name.split(/::/)
  while(v = ary.shift)
    ret.unshift(((ret.size == 0) ? eval(v) : ret[0].const_get(v)))
  end
  ret
end
 
module Foo
  module Bar
    module Baz; end
  end
end
 
require 'benchmark'
Benchmark.bm(9){ |x|
  x.report("nesting"){
    10000.times{
      nesting(Foo::Bar::Baz)
      nesting(Foo::Bar)
      nesting(Foo)
    }
  }
}
 
$ ruby test.rb
               user     system      total        real
nesting    0.650000   0.070000   0.720000 (  0.746397)

お、微妙に速い。

[Ruby] if文と三項演算子はどっちが速い?

こちらも心配になったので計ってみた。Ruby的には条件演算子と言うべきなのかな。

$ cat test4.rb
require 'benchmark'
Benchmark.bm(3){ |x|
  x.report("if"){100000.times{if true; a = 1 else; a = 2;end}}
  x.report("?:"){100000.times{a = true ? 1 : 2}}
}
 
$ ruby test4.rb
         user     system      total        real
if   0.090000   0.060000   0.150000 (  0.166605)
?:   0.060000   0.090000   0.150000 (  0.163028)

ちょっと三項演算子の方が速いかな。何回かやるとifの方が速くなる場合もあるけど、平均取ると三項演算子の方が速いっぽい。

[Ruby] eachとinjectどっちが速い?

おまけ。ちょっと差がありすぎるな。使い方あってるよね?ちょっと心配だ・・・(苦笑)。

$ cat test5.rb
require 'benchmark'
Benchmark.bm(8){ |x|
  x.report("each"){a = []; 10000.times{(0..100).each {|v| a << v}}}
  x.report("inject"){10000.times{(0..100).inject([]){|a, v| a << v}}}
}
 
$ ruby test5.rb
              user     system      total        real
each      1.380000   1.180000   2.560000 (  2.593192)
inject   11.740000   1.820000  13.560000 ( 13.631210)


更新 設定