「use Imager; - 今日のCPANモジュール[まぐまぐ!]」を読んでImagerを使いたくなったのとImage::Imlib2が気になったので、Image::MagickとGD::Imageをあわせて4つのモジュールの処理速度を比べるベンチマークをとってみた(初use Benchmark;)。 題材はあるURLにあるWeb上の画像をとってきて横幅120pxにリサイズしてファイルに書き出すというよく使うもの。 Image::MagickだとReadメソッドに直接URLを渡せて便利だけど、他のモジュールにはそんな便利な機能はないのでLWP::Simpleのgetを使ってデータをとってきて渡す。さらにImage::Imlib2では生データの渡し方がぼくには難しくてわからなかったので(ってかできるかな?)、一度ファイルに保存してから再び読み込む。コードはこんな感じ。めんどくさいのでGDのリサイズにImage::Resizeを使った。
use strict;
use warnings;
use Benchmark;
use Imager;
use Image::Magick;
use LWP::Simple;
use GD::Image;
use Image::Resize;
use Image::Imlib2;
my $url = "http://yusukebe.com/archives/files/040729/DSC08431.jpg";
my $width = 120;
Benchmark::timethese(100, {
'Image::Magick' => \&with_ImageMagick,
'Imager' => \&with_Imager,
'GD::Image' => \&with_GDImage,
'Image::Imlib2' => \&with_ImageImlib2
});
sub with_ImageMagick {
my $img = Image::Magick->new;
$img->Read($url);
my($source_width,$source_height) = $img->Get('width','height');
my $height = $width/$source_width*$source_height;
$img->Resize( width => $width , height => $height);
$img->Write('out.jpg');
}
sub with_Imager {
my $data = get($url);
my $img = Imager->new;
$img->read( data => $data );
$img = $img->scale( xpixels => $width );
$img->write( file => 'out.jpg');
}
sub with_GDImage {
my $data = get($url);
my $gd = GD::Image->newFromJpegData($data);
my $img = Image::Resize->new($gd);
my $height = $width/$img->width*$img->height;
$gd = $img->resize($width, $height);
open( OUT, "> out.jpg");
print OUT $gd->jpeg;
close OUT;
}
sub with_ImageImlib2 {
my $data = get($url);
open( OUT, "> in.jpg");
print OUT $data;
close OUT;
my $img = Image::Imlib2->load("in.jpg");
my $height = $width/$img->width*$img->height;
$img = $img->create_scaled_image($width,$height);
$img->save("out.jpg");
}
で、いざベンチマーク、100回ずつまわしてみる。画像を毎回Webから読むので相手方のWebサーバーのレスポンスに結果が左右されるがだいたいこんな感じ。
GD::Image: 16 wallclock secs ( 4.09 usr + 0.16 sys = 4.25 CPU) @ 23.53/s (n=100) Image::Imlib2: 21 wallclock secs ( 0.56 usr + 0.10 sys = 0.66 CPU) @ 151.52/s (n=100) Image::Magick: 27 wallclock secs ( 6.02 usr + 0.63 sys = 6.65 CPU) @ 15.04/s (n=100) Imager: 29 wallclock secs ( 7.27 usr 0.32 sys + 0.01 cusr 0.11 csys = 7.71 CPU) @ 13.18/s (n=100)
おおお、Image::Imlib2確かに超絶速い。 というわけで1位がダントツでImage::Imlib2、それ以下2位GD::Image、3位Image::Magick、4位Imagerでした。

