Edited at

Ruby から ImageMagick を使う方法の速度を比較する

More than 3 years have passed since last update.

比較しているのはよくある適当な 1080 x 236 px の JPEG 画像を ImageMagick を使って適当な位置を切り取ってくるという処理をして速度を比較しています。

比較したのは以下の3つ。


  • MiniMagick

  • ファイル渡しで ImageMagick を直接叩く

  • パイプ渡しで ImageMagick を直接叩く


ベンチマークのスクリプト

require 'benchmark'

require 'mini_magick'
require 'tempfile'
require 'open3'

TARGET = 'common_case_1.jpg'

N = 1000

IMAGE = File.open(TARGET).read

def minimagick
piece_image = MiniMagick::Image.read(IMAGE)
piece_image.crop('450x556+0+0')
image = piece_image.to_blob
end

def imagemagick_file
Tempfile.open('tmp_piece_input', './') do |input_image|
Tempfile.open('tmp_piece_output', './') do |output_image|
input_image.write IMAGE
`convert -crop 450x556+0+0 #{input_image.path} #{output_image.path}`
output_image.read
end
end
end

def imagemagick_pipe
image,_ = Open3.capture2("convert -crop 450x556+0+0 jpeg:- jpeg:-", stdin_data: IMAGE, binmode: true)
end

Benchmark.bm(20) do |x|
x.report('minimagick:') { N.times { minimagick } }
x.report('imagemagick_file:') { N.times { imagemagick_file } }
x.report('imagemagick_pipe:') { N.times { imagemagick_pipe } }
end


結果

                           user     system      total        real

minimagick: 0.910000 2.490000 30.950000 ( 33.037064)
imagemagick_file: 0.300000 1.470000 26.260000 ( 27.954511)
imagemagick_pipe: 0.590000 1.420000 24.920000 ( 25.720133)

子プロセス分での処理をなんだかうまく表示できないのでわかりづらいが total から user + system 引いた分。

パイプ渡しで叩くのが早いっぽい。


考察

結局 ImageMagick 内での処理が一番かかり、ファイルの読み書きで速度が大幅に低下しているというわけではないようにみえるが、ファイルの読み書きをなくせばある程度は早くなる。JPEG の処理が一番処理を食うのであろうことが想像される。