カテゴリ別 2003年 | 2004年 | 2005年 | 2006年 | 2007年 | 2008年
知り合いサイト: よんだもの / 暴想 / Linuxでやる夫 / 新宿Vipper / 僕だけが幸せになればいいのに。
RedHanded の YARV is Ruby, It Is, It Really Is を見てベンチマークをしてみたところ、挙げられている [ruby-core:9825] よりもやけに良い結果になりました。遅い CPU だから差が顕著にでるのかな。
PureImage on 2ch.net - 航海日誌 (2007-01-04)
パフォーマンス向上についてはStringを画像コンテナに使うアイデアがあるので多少良くなる可能性はあり.精進します.YARVがデフォルトになれば,3倍以上速くなる予感がしているので,いいライブラリができればNative拡張ライブラリな画像処理ライブラリの意義が薄れるかもしれませんね.
ベンチをとるついでに PureImage のサンプルプログラムの実行時間を調べてみました。少なくとも 2 倍は速くなりそうです。計算が多くなるほど差が出てくるかも。time コマンド使用、3 回平均、単位は秒です。
| プログラム | 1.9 | 1.9+yarv | 比 |
|---|---|---|---|
| alpha.rb | 0.928 | 0.328 | 2.8 |
| filter.rb | 2.818 | 1.225 | 2.3 |
| filter2.rb | 2.532 | 1.463 | 1.7 |
| graph.rb | 0.789 | 0.345 | 2.3 |
| hello.rb | 0.436 | 0.409 | 1.1 |
| shape.rb | 1.427 | 0.512 | 2.8 |
ちなみにボトルネックを調べようと -rprofile 付きで実行したところ
% cumulative self self total time seconds seconds calls ms/call ms/call name 0.00 1.24 0.00 1 0.00 1240.00 #toplevel
という悲しい結果になりました。プロファイラはまだ未対応のようですね。
1.9.0 では IO.getc や String#[] が Integer ではなく一文字の String を返します。とりあえずの回避策として String#ord を追加するパッチをあげておきます。
--- pureimage.rb 2007-01-06 02:58:26.000000000 +0900
+++ pureimage.rb 2007-01-06 03:02:59.000000000 +0900
@@ -174,7 +174,7 @@
width = read_short(inp)
pixels = Array.new(width * @height)
for i in 0..(pixels.length - 1)
- pixels[i] = inp.getc
+ pixels[i] = inp.getc.ord
end
@font[code] = CharImage.new(width, pixels)
rescue
@@ -186,13 +186,13 @@
private :read_char_image
def read_short(inp)
- return (inp.getc & 0xff) << 8 | (inp.getc & 0xff)
+ return (inp.getc.ord & 0xff) << 8 | (inp.getc.ord & 0xff)
end
private :read_short
def read_int(inp)
- return (inp.getc & 0xff) << 24 | (inp.getc & 0xff) << 16 \
- | (inp.getc & 0xff) << 8 | (inp.getc & 0xff)
+ return (inp.getc.ord & 0xff) << 24 | (inp.getc.ord & 0xff) << 16 \
+ | (inp.getc.ord & 0xff) << 8 | (inp.getc.ord & 0xff)
end
private :read_int
@@ -837,26 +837,26 @@
# IHDR: Read header.
width = to_int(data, 0)
height = to_int(data, 4)
- depth = data[8].to_i
- color_type = data[9].to_i
- compress = data[10].to_i
- filter = data[11].to_i
- interlace = data[12].to_i
+ depth = data[8].ord
+ color_type = data[9].ord
+ compress = data[10].ord
+ filter = data[11].ord
+ interlace = data[12].ord
# Check support PNG format.
if depth != 8 then
- raise "Not support color depth: " + depth
+ raise "Not support color depth: #{depth}"
end
if color_type != 2 && color_type != 6 then
- raise "Not support color type: " + color_type
+ raise "Not support color type: #{color_type}"
end
if compress != 0 then
- raise "Not support compress method: " + compress
+ raise "Not support compress method: #{compress}"
end
if filter != 0 then
- raise "Not support filter method: " + filter
+ raise "Not support filter method: #{filter}"
end
if interlace != 0 then
- raise "Not support filter method: " + interlace
+ raise "Not support filter method: #{interlace}"
end
elsif type == "IDAT" then
# IDAT: Read pixel data.
@@ -969,10 +969,10 @@
private :write_int
def to_int(str, offset)
- value = str[offset].to_i
- value = (value << 8) | (str[offset + 1].to_i & 0xff)
- value = (value << 8) | (str[offset + 2].to_i & 0xff)
- value = (value << 8) | (str[offset + 3].to_i & 0xff)
+ value = str[offset].ord
+ value = (value << 8) | (str[offset + 1].ord & 0xff)
+ value = (value << 8) | (str[offset + 2].ord & 0xff)
+ value = (value << 8) | (str[offset + 3].ord & 0xff)
return value
end
private :to_int
@@ -993,10 +993,10 @@
private :read_chunk
def read_int(inp)
- value = inp.getc() & 0xff
- value = (value << 8) | (inp.getc() & 0xff)
- value = (value << 8) | (inp.getc() & 0xff)
- value = (value << 8) | (inp.getc() & 0xff)
+ value = inp.getc.ord & 0xff
+ value = (value << 8) | (inp.getc.ord & 0xff)
+ value = (value << 8) | (inp.getc.ord & 0xff)
+ value = (value << 8) | (inp.getc.ord & 0xff)
return value
end
private :read_int
最近のコメント:
RSS
![]()
This work is licensed under a
Creative Commons License
(note: text only. w/o web design, citations, (re)distributed softwares).