自作Rubyプログラム

/TOP/自作Rubyプログラム/ Ruby/libpng

Ruby/libpng

>> Ruby/libpng 0.3.4

[PNG Programming Resource] もどうぞ。

Ruby/libpng は 将来有望なグラフィックフォーマットである PNG の読み書きを Ruby で行なうためのライブラリです。
PNG のリファレンスライブラリである libpng のラッパーとなっています。

事前に libpngzlib をインストールしておいてください。
最近の Cygwin では両方インストールされます。されていないようでしたら、 setup.exe でアップデートしておいてください。
インストール方法などは添付の readme.ja.txt を読んでください。

ToDo&変更点とか)

パフォーマンステスト

2001/02/13

libpng 付属の pngtest とそれを Ruby にポートした pngtest.rb (Ruby/libpng の test ディレクトリにあります) の実行速度を比較しました。 それぞれ 50 回実行です。
環境は Windows 2000 SP1/ Cygwin 1.1.8 / Ruby 1.6.2 / libpng-1.0.9 / Ruby/libpng 0.3.5 です。

$time test.sh
real    1m11.844s
user    1m6.080s
sys     0m6.400s
$time test_rb.sh
real    0m12.138s
user    0m8.730s
sys     0m4.170s

相当遅いですね。。。ボトルネックを見つけてみます。

$ruby -rprofile pngtest.rb pngtest.png
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 66.24   132.74    132.74    19232     6.90    28.08  Range#each
  8.41   149.60     16.86   105084     0.16     0.16  Fixnum#+
  5.97   161.56     11.97    76407     0.16     0.16  Fixnum#==
  5.08   171.75     10.19    75348     0.14     0.14  Graphics::PNG::RowInfo#bit_depth
  4.43   180.64      8.89    56511     0.16     0.16  Numeric#===
  4.39   189.44      8.80    56511     0.16     0.16  String#[]
  1.37   192.19      2.74    20016     0.14     0.14  Graphics::PNG::RowInfo#color_type
  1.31   194.82      2.63    19486     0.14     0.14  Fixnum#>
  0.92   196.67      1.85     1048     1.77   188.10  Proc#call
  0.84   198.36      1.68       21    80.14  9520.81  Fixnum#upto
  0.24   198.83      0.47     1449     0.33   135.67  Graphics::PNG::Writer#write_row
  0.20   199.23      0.40     3552     0.11     0.11  Array#[]
  0.18   199.60      0.37     1449     0.26     0.95  Graphics::PNG::Reader#read_row
  0.06   199.72      0.12      283     0.43     0.43  IO#write
  0.06   199.84      0.12      271     0.44     0.89  Kernel.print
  0.05   199.94      0.10      393     0.25     0.25  Graphics::PNG::RowInfo#width
  0.04   200.03      0.09      393     0.23     0.23  Array#[]=
  0.04   200.12      0.09      393     0.23     0.23  Graphics::PNG::RowInfo#channels
  0.03   200.18      0.06        3    20.00 66699.00  PngTest#test_one_file
..........

ということで、フィルタやサンプル数を数えるコールバックルーチン部分がボトルネックのようです。 試しに pngtest.rb からコールバックルーチンを取り除いて実行してみると、

$time test_rb.sh
real    0m17.025s
user    0m11.720s
sys     0m5.750s

オリジナルの pngtest とあまり変わらない値になりました。 C で書いた拡張ライブラリのコールバックルーチンを定義可能にするべきですね。

test.sh と test_rb.sh は以下の通りです。

--- test.sh
#!/bin/sh
i=0
while [ $i -lt 50 ]
do
  ./pngtest pngtest.png > /dev/null
  i=`expr $i + 1`
done

--- test_rb.sh
#!/bin/sh
i=0
while [ $i -lt 50 ]
do
  ruby pngtest.rb pngtest.png > /dev/null
  i=`expr $i + 1`
done

/TOP/自作Rubyプログラム/ Ruby/libpng

--EOF--