まだ重たいCMSをお使いですか?
毎秒1000リクエスト を捌く超高速CMS「adiary

2007/04/26(木)perl の Encode で find_encode は使えるのか?

perl tips - Encodeを速く使う方法によると、find_encoding を使うと、Encode による文字変換が早くなるらしいということで実験してみました。

実験条件

  • use utf8 しない(use utf8 はトラブルが多すぎてやってられないので)。
  • 変換前も変換後も utf8 フラグは立っていないこと。
  • 実験用データとして、42KBのテキストファイル(EUC-JP, 日本語半分ぐらい)を用意。

ソースはこんな感じです。引数に処理したい euc-jp のテキストファイル名を与えます。

use strict;
use Benchmark;
use Encode;
use Encode::Guess qw(euc-jp shiftjis iso-2022-jp);

my $euc = join('', <>);
my $utf = $euc;
Encode::from_to($utf, "euc-jp", "utf8");

my $euc_obj = find_encoding('euc-jp');
my $utf_obj = find_encoding('utf8');

my %test;
$test{fromto_u2e} = sub {
	my $x = $utf;
	Encode::from_to($x, "utf8", "euc-jp");
};
$test{fromto_e2u} = sub {
	my $x = $euc;
	Encode::from_to($x, "euc-jp", "utf8");
};
$test{find1_u2e} = sub {
	my $x = $euc_obj->encode( $utf_obj->decode($utf) );
};
$test{find1_e2u} = sub {
	my $x = $utf_obj->encode( $euc_obj->decode($euc) );
};
$test{find2_u2e} = sub {
	my $x = $utf;
	Encode::_utf8_on($x);
	$x = $euc_obj->encode( $x );
};
$test{find2_e2u} = sub {
	my $x = $euc_obj->decode($euc);
	Encode::_utf8_off($x);
};
$test{encode_u2e} = sub {
	my $x = $utf;
	Encode::_utf8_on($x);
	$x = encode('euc-jp', $x);
	print $x;
};
$test{decode_e2u} = sub {
	my $x = decode('euc-jp', $euc);
	Encode::_utf8_off($x);
};
timethese(1000,\%test);

結果は次のとおりになりました。

方式utf8 to euceuc to utf8
from_to100.26/s336.84/s
find_encoding103.92/s380.20/s
find_encoding + _utf_on/off357.21/s397.93/s
encode/decode304.76/s350.68/s

utf8からutf8(フラグ付き)への変換=utf8文字列の検証が入らないので速くなりましたが、ほかは大して変わりません。use utf8 しない環境では find_encodeを使うほどでもないなぁーという感じもします。

つまり、utf8を他の文字コードに変換する場合は、Encode::_utf8_on() + encode を使うと速い。短い文字列を多量に処理するのでなければ、ほかは大して変わらない。ということだと思います。

というわけで

早速adiaryに組み込んでみよう(笑)