5/21 Genesis Lightning Talks vol.16 開催されます

http://wiki.somethingnew2.com/lt/index.php?Events%2F2009%2F05
時間:2009年5月21日(木) 19:30-21:00(19:00開場)
場所:AIP cafe -- http://sites.google.com/site/aipcafe/Home
参加費:無料
今回のテーマは「笑い」です。

ナカオさんにもイベント告知していただいた。
Genesis Lightning Talks vol.16@Fukuoka - ナカオ日記−フリーランスの轍

RBCメーリングリストに告知を流したら、主催者のようぞうさんがフォローしてくれた。ので引用。

Genesis Lightning Talksってのは、さとうが主催しているイベントで
毎回テキトーなお題をピックアップし、それについて5分で語
るという
へんてこりんな集会です。

で、東京の片隅で毎月こじんまりと開催していたへんてこりんな集会が
渕上さんの熱い情熱とITテクノロジーの融合により(←美化しすぎ
w)
東京 ←→ 福岡 間をustream.tv経由でほ
ぼリアルタイム中継するという
イベントに昇華されました。

Rubyにフォーカスした技術イベントでもないですし、Businessとは
縁の(¥の)遠いイベントですが、そのかわりかなり敷居の低いものに
なっていると自負しておりますので、気軽にご参加頂ければと思います。

会場は
・東京会場
 → オラクル青山センター 14階会議室
・福岡会場
 → AIPカフェ
ですが、NET参加ならustream.tvで世界中どこからでもjoin
可能です。

・東京会場のカメラ
 → http://www.ustream.tv/channel/genesislightningtalks
・福岡会場のカメラ
 → http://www.ustream.tv/channel/genesislightningtalkssatellite

ustream.tvでの参加でも、東京会場のチャットに書き込みすると!
なんと東京会場のスクリーンにはその書き込みがリアルタイムで見れる!
という仕組みが導入されていたり、もします。

ということで、興味のある方は是非ご参加下さい。
よろしくお願い致します。

お時間ある方は是非お越し下さい。お待ちしております。

fixing do_mysql hanging or install problems on mac os x

MerbなのでDataMapper。デフォルトDBはsqlite3だが、MySQL使う場合、do_mysqlをインストール
fixing do_mysql hanging or install problems on mac os x

% sudo gem install do_mysql -- --with-mysql-dir=/usr/local/mysql/ --with-mysql-config=/usr/local/mysql/bin/mysql_config 
Building native extensions.  This could take a while...
Successfully installed do_mysql-0.9.11
1 gem installed
Installing ri documentation for do_mysql-0.9.11...

Enclosing class/module 'mDO' for module Mysql not known
Installing RDoc documentation for do_mysql-0.9.11...

Enclosing class/module 'mDO' for module Mysql not known

% gem list --local | grep do_ 
do_mysql (0.9.11)
do_sqlite3 (0.9.11)

では、Windowsではどうやればいいのだろう?

TokyoCabinetでハッシュいろいろ

mixi engineer blogmacで試してみたので、そのログ
TokyoCabinetのインストールはTokyoCabinet/TokyoTyrant を Rails で使う - なんとなく日記を参考に、最新バージョンをとってきて、./configure && make && sudo make install、あとRubyバインディングも併せてインストール。
テストコードそのままだと、Macではprocディレクトリがないため、メモリサイズが取得できない。のでmemory_usageメソッド(ps -lの出力結果の「RSS」列を取得)を書き換えたのが以下。

# tchash.rb
require 'tokyocabinet'
include TokyoCabinet

def memory_usage
  return `ps -l #{$$} | awk '{print $9}'`.gsub(/.+\n(\d+).*/, '\1').chomp.to_i / 1024.0
end

rnum = ARGV.length > 0 ? ARGV[0].to_i : 1000000

time = Time.now
size = memory_usage
if ARGV.length > 1
  db = ADB::new
  db.open(ARGV[1] + "#bnum=" + rnum.to_s + "#mode=wct#xmsiz=0") || raise("open failed")
  (0...rnum).each do |i|
    buf = sprintf("%08d", i)
    db.put(buf, buf)
  end
  time = Time.now - time
  GC.start
  size = memory_usage - size
  db.close
else
  hash = {}
  (0...rnum).each do |i|
    buf = sprintf("%08d", i)
    hash[buf] = buf
  end
  time = Time.now - time
  GC.start
  size = memory_usage - size
end

printf("Time: %.3f sec.\n", time)
printf("Usage: %.3f MB\n", size)
ruby hash% ruby -v tchash.rb 
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 8.384 sec.
Usage: 240.781 MB

on-memory hash% ruby -v tchash.rb 1000000 '*'
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 2.953 sec.
Usage: 71.375 MB

on-memory tree% ruby -v tchash.rb 1000000 '+'
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 2.705 sec.
Usage: 46.914 MB

hash database% ruby -v tchash.rb 1000000 'foo.tch'
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 17.326 sec.
Usage: 4.578 MB
                            
B+ tree database% ruby -v tchash.rb 1000000 'foo.tcb'
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 4.253 sec.
Usage: 5.875 MB

fixed-length database% ruby -v tchash.rb 1000000 'foo.tcf'
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 4.220 sec.
Usage: 244.688 MB

table database% ruby -v tchash.rb 1000000 'foo.tct'
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
Time: 21.121 sec.
Usage: 4.629 MB

ADB#open(name)の引数はmovedに倣った

Open a database.
`name' specifies the name of the database.
If it is "*", the database will be an on-memory hash database.
If it is "+", the database will be an on-memory tree database.
If its suffix is ".tch", the database will be a hash database.
If its suffix is ".tcb", the database will be a B+ tree database.
If its suffix is ".tcf", the database will be a fixed-length database.
If its suffix is ".tct", the database will be a table database.
Otherwise, this function fails. Tuning parameters can trail the name, separated by "#".
Each parameter is composed of the name and the value, separated by "=".
On-memory hash database supports "bnum", "capnum", and "capsiz".
On-memory tree database supports "capnum" and "capsiz".
Hash database supports "mode", "bnum", "apow", "fpow", "opts", "rcnum", and "xmsiz".
B+ tree database supports "mode", "lmemb", "nmemb", "bnum", "apow", "fpow", "opts", "lcnum", "ncnum", and "xmsiz".
Fixed-length database supports "mode", "width", and "limsiz".
Table database supports "mode", "bnum", "apow", "fpow", "opts", "rcnum", "lcnum", "ncnum", "xmsiz", and "idx".
If successful, the return value is true, else, it is false.
The tuning parameter "capnum" specifies the capacity number of records.
"capsiz" specifies the capacity size of using memory.
Records spilled the capacity are removed by the storing order.
"mode" can contain "w" of writer, "r" of reader, "c" of creating, "t" of truncating, "e" of no locking, and "f" of non-blocking lock.
The default mode is relevant to "wc".
"opts" can contains "l" of large option, "d" of Deflate option, "b" of BZIP2 option, and "t" of TCBS option.
"idx" specifies the column name of an index and its type separated by ":".
For example, "casket.tch#bnum=1000000#opts=ld" means that the name of the database file is "casket.tch", and the bucket number is 1000000, and the options are large and Deflate.

繰り越し:
今回は、Hashへの100万回書き込みだった訳だが、他にもいろいろ試してみたい。実装ものぞいてみたい。

近くでやってたので

そんなに興味がある訳ではないけれど、近く(佐賀市)でやってたので行ってきた。
普通に自然と、気持ち高揚したので、写真などとってみた。
イベント名は。。。覚えてない。たこ焼きと鶏の唐揚げ食った。









GLT vol.15お疲れさまでした

http://wiki.somethingnew2.com/lt/index.php?Events%2F2009%2F04

Vol.15は無事終了しました。参加頂いたみなさま、サポート頂いたみなさま、どうもありがとうございました

id:nakaoさんのご尽力により、福岡天神のAIPcafeからの中継も実現でき、また「オチをつけられるようになってる!」とyoozoosatoお褒め?の言葉を頂いた。非常に楽しい夜でした。
当日の模様は、こちらで見ることができます。
・ちょっとお酒が入りすぎたなと反省(冷静に参加できてない)
・開催主旨にもあるように「みんなが楽しめて、みんなに喜んでもらえるWEB系サービスを楽しく作りたい!」ってところを意識してやっていきたい。改めて。
・ありがとうございました。
・次回は5/21(木)開催予定です。

4/23 19:30- @AIPcafeでお会いしましょう

http://wiki.somethingnew2.com/lt/index.php?Events%2F2009%2F04
第15回のお題はDBですが、Databaseについて語らなければいけない、という訳ではありません。

タイトルがDB、ないしはDBをタイトルに含むであれば、トークする内容はあなた次第

詳しくは、上記Wikiの開催主旨をご覧頂きたいです。お気軽に覗きにきてもらえれば嬉しいです。

How JRuby Makes Ruby Fast を読んで、試したログ

(20090423 補足追加)

How JRuby Makes Ruby Fast – Charles Oliver Nutter – Java, Ruby, and JVM guy trying to make sense of it allベンチマークを実行してみた。解釈間違い等あれば、ご指摘ください。ベンチコードは参照元のまま、以下の通り。いろんな最適化レベルでパフォーマンスはかるには格好のものらしい。

def tak x, y, z
  if y >= x
    return z
  else
    return tak( tak(x-1, y, z),
                tak(y-1, z, x),
                tak(z-1, x, y))
  end
end

require 'benchmark'

N = (ARGV.shift || 1).to_i

Benchmark.bm do |make|
  N.times do
    make.report do
      i = 0
      while i<10
        tak(24, 16, 8)
        i += 1
      end
    end
  end
end

で、まずRuby1.8.7と1.9、JRubyインタプリタモードで比較

zsh% ruby -v bench_tak.rb 5
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.6.0]
      user     system      total        real
 17.330000   0.100000  17.430000 ( 17.878270)
 17.320000   0.100000  17.420000 ( 17.865022)
 17.370000   0.100000  17.470000 ( 17.916406)
 17.370000   0.090000  17.460000 ( 17.923585)
 17.380000   0.120000  17.500000 ( 18.020999)

zsh% ~/r191/ruby -v bench_tak.rb 5
ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-darwin9.6.0]
      user     system      total        real
  3.500000   0.020000   3.520000 (  3.610300)
  3.490000   0.020000   3.510000 (  3.600984)
  3.490000   0.020000   3.510000 (  3.590130)
  3.490000   0.020000   3.510000 (  3.625073)
  3.490000   0.020000   3.510000 (  3.626134)

zsh% jruby -v -X-C bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
 19.569000   0.000000  19.569000 ( 19.503000)
 20.894000   0.000000  20.894000 ( 20.894000)
 21.127000   0.000000  21.127000 ( 21.128000)
 21.126000   0.000000  21.126000 ( 21.126000)
 21.180000   0.000000  21.180000 ( 21.180000)

「-X-C」オプションは「disable all compilation」、インタプリタモード、かつ「client VM」で実行した結果。
次は、「Server VM」で実行してみる

zsh% jruby --server -v -X-C bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  7.832000   0.000000   7.832000 (  7.776000)
  8.012000   0.000000   8.012000 (  8.012000)
  8.187000   0.000000   8.187000 (  8.187000)
  8.193000   0.000000   8.193000 (  8.193000)
  8.201000   0.000000   8.201000 (  8.201000)

インタプリタモードなのでJVMバイトコードコンパイルされていない
(追記:2009/04/23 start)

ソフトウェアの実行時にコードのコンパイルを行い実行速度の向上を図る方式である。通常のコンパイラソースコード(あるいは中間コード)から対象CPUの機械語への変換を実行前に(コンパイル時に)行う。通常のコンパイラソースコード(あるいは中間コード)から対象CPUの機械語への変換を実行前に(コンパイル時に)行う。これをJITと対比して事前コンパイル (Ahead Of Time, AOT) コンパイルと呼ぶ。

インタプリタ方式と比較すると性能面では以下のような差が出てくる

* 機械語に変換されるため、コンパイル後の実行速度はインタプリタ方式の数倍の性能となる
* モジュールやクラス、関数のロード時にコンパイルが行われるため、プログラムの起動には時間がかかる
* 一度コンパイルしたコードを保持するために、より多くのメモリ容量を必要とする

実行時コンパイラ - Wikipedia
(追記:2009/04/23 end)
なので、次は「Server VM」で、「コンパイルモード」で実行してみる。ただし最適化は行われていない
(追記:2009/04/23 start)
Server VM と Client VM の違い

The "server" VM differs from the default "client" VM in that it will optimistically inline code across calls and optimize the resulting code as a single unit. This obviously allows it to eliminate costly x86 CALL operations, but even more than that it allows optimizing algorithms which span multiple calls.

The difference is the way that it uses the Just-in-Time compilers.

The client mode uses a JIT compiler (originally from Apple), which basically compiles the java bytecodes into native machine code as soon as it is loaded.

The server mode uses a JIT compile from Sun, which uses the Java interpreter on the java bytecodes, for a while. Once enough data has been collected about the java class, it is then JIT compiled to native machine code, using the profiling data that it has collected to optimize the compilation.

Henry

JVM Server Mode vs Client Mode (Java in General forum at Coderanch)
Client VM はコードがロードされた際に逐一コンパイルが行われる。Server VM は呼び出すコードもまとめてコンパイルされる。また複数回の実行により最適化される。長時間存続するアプリケーションに向いている。
(追記:2009/04/23 end)

zsh% jruby --server -v -J-Djruby.astInspector.enabled=false bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  4.889000   0.000000   4.889000 (  4.834000)
  3.572000   0.000000   3.572000 (  3.572000)
  3.554000   0.000000   3.554000 (  3.554000)
  3.558000   0.000000   3.558000 (  3.558000)
  3.551000   0.000000   3.551000 (  3.551000)

astはAbstract Structure Tree:抽象構文木のことだろう。最適化されていないとはどういうことかというと、JustInTimeでネイティブコードに変換しているかららしい。(del 2009/04/23)
(追記:2009/04/23 start)

Because we're now JITing Ruby code as JVM bytecode, and the JVM eventually JITs JVM bytecode to native code, our Ruby code actually starts to benefit from the JVM's built-in optimizations.

RubyのコードはJVM bytecodeにJITコンパイルされ、JVM機械語に変換する。上記の実行は、その流れでJVMのbuilt-inな最適化の恩恵を得始めた初期段階。最低限の最適化ということみたい。
(追記:2009/04/23 end)
次は、デフォルトの最適化レベル「heap scope elimination」での実行。局所変数をインメモリではなく、外部のコンテキストから参照されない場合はJava局所変数としてコンパイルする。またそれらはCPUのレジスタに格納されるとのことらしい。

zsh% jruby --server -v bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  3.431000   0.000000   3.431000 (  3.372000)
  2.347000   0.000000   2.347000 (  2.348000)
  2.334000   0.000000   2.334000 (  2.334000)
  2.358000   0.000000   2.358000 (  2.358000)
  2.345000   0.000000   2.345000 (  2.345000)

ちなみにオプションなしの場合より、少し早い

zsh% jruby -v bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  3.646000   0.000000   3.646000 (  3.575000)
  2.578000   0.000000   2.578000 (  2.578000)
  2.575000   0.000000   2.575000 (  2.575000)
  2.566000   0.000000   2.566000 (  2.567000)
  2.581000   0.000000   2.581000 (  2.581000)

さて、次は「backtrace-only frames」。このへんから疲れてきた。
(追記:2009/04/23 start)
ただ、

This is where we start to break Ruby a bit, though there are ways around it.

なので、副作用に気をつけはじめなくてはならない
(追記:2009/04/23 start)

zsh% jruby --server -v -J-Djruby.compile.frameless=true bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  3.121000   0.000000   3.121000 (  3.064000)
  2.199000   0.000000   2.199000 (  2.199000)
  2.205000   0.000000   2.205000 (  2.205000)
  2.203000   0.000000   2.203000 (  2.202000)
  2.174000   0.000000   2.174000 (  2.174000)

次も同じオプションだが、

You'll notice the command line here is the same; that's because we're venturing into more and more experimental code, and in this case I've actually forced "frameless" to be "no heap frame" instead of "backtrace-only heap frame".

とのこと。だが「frame」がどういうものか分かってないので・・・
(追記:2009/04/23 start)
frameはJVMのスタック領域のこと?
(追記:2009/04/23 end)

zsh% jruby --server -v -J-Djruby.compile.frameless=true bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  3.117000   0.000000   3.117000 (  3.060000)
  2.151000   0.000000   2.151000 (  2.151000)
  2.144000   0.000000   2.144000 (  2.144000)
  2.144000   0.000000   2.144000 (  2.144000)
  2.154000   0.000000   2.154000 (  2.154000)

つぎは、「some optimizations for math operators」

zsh% jruby --server -v -J-Djruby.compile.frameless=true -J-Djruby.compile.fastops=true bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  2.830000   0.000000   2.830000 (  2.763000)
  1.881000   0.000000   1.881000 (  1.882000)
  1.870000   0.000000   1.870000 (  1.871000)
  1.867000   0.000000   1.867000 (  1.867000)
  1.870000   0.000000   1.870000 (  1.870000)

So JRuby has experimental "fast math" operations to turn most Fixnum math operators into static calls rather than dynamic ones, allowing most math operations to inline directly into the caller.

なので、

This version of "fast ops" makes it impossible to override Fixnum#+ and friends, since whenever we call + on a Fixnum it's going straight to the code.

という副作用があるよ、らしい。んー、だんだん引用ばかりになってきた。
次は、各スレッドで他のスレッドが生きているかチェックする機能をオフにする模様

zsh% jruby --server -v -J-Djruby.compile.frameless=true -J-Djruby.compile.fastops=true -J-Djruby.compile.positionless=true -J-Djruby.compile.threadless=true bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  2.777000   0.000000   2.777000 (  2.721000)
  1.808000   0.000000   1.808000 (  1.808000)
  1.813000   0.000000   1.813000 (  1.813000)
  1.823000   0.000000   1.823000 (  1.823000)
  1.814000   0.000000   1.814000 (  1.814000)

次は、これまでの実験的な最適化をまとめたもの?またそれらの最適化がsafetyなものかを調査する。また動的な呼び出しをインライン化する試みでもあるらしい?分かってないなー、おれ。

zsh% jruby --server -v --fast bench_tak.rb 5
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-21 r6586) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
      user     system      total        real
  2.143000   0.000000   2.143000 (  2.076000)
  1.087000   0.000000   1.087000 (  1.087000)
  1.104000   0.000000   1.104000 (  1.104000)
  1.098000   0.000000   1.098000 (  1.098000)
  1.096000   0.000000   1.096000 (  1.096000)
zsh%

・最適化することによる副作用分かっていない
・frameの概念わかってない
・コードのインライン化とはどういうことか分かってない
・まだ続きがあるが、とりあえず今日はここまで
・ひきつづき調べたい