2013/03/04

Unicode::UTF8 がガチ爆速すぎる

あんまり深読みしてないんだけど、Unicode::UTF8 が超速い。

おなじみ Encode との比較で、PODには 600% 速いって書いてあるけど、手元で試す感じだとだいたい 350~650% 速い。つまり、マジ速い。

Benchmark: timing 350000 iterations of Encode, Unicode::UTF8...
    Encode:  5 wallclock secs ( 4.41 usr +  0.00 sys =  4.41 CPU) @ 79365.08/s (n=350000)
Unicode::UTF8:  0 wallclock secs ( 0.72 usr +  0.00 sys =  0.72 CPU) @ 486111.11/s (n=350000)
                  Rate        Encode Unicode::UTF8
Encode         79365/s            --          -84%
Unicode::UTF8 486111/s          512%            --

文字列の長さは短いの長いの試したけど、どのパターンでも U::UTF8 が速い様子。

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode qw();
use Unicode::UTF8 qw();

use Benchmark qw/timethese cmpthese/;

my $str = <<"_TXT_";
もう、三十七歳になります。こないだ、或る先輩が、よく、まあ、君は、生きて来たなあ、としみじみ言っていました。私自身にも、三十七まで生きて来たのが、うそのように思われる事があります。
_TXT_
my $enc = Encode::find_encoding('utf8');

my $result = timethese (350_000, {
    'Encode'        => '&logic1;',
    'Unicode::UTF8' => '&logic2;',
});

cmpthese $result;


sub logic1 {
    $enc->decode(
        $enc->encode($str)
    );
}

sub logic2 {
    Unicode::UTF8::decode_utf8(
        Unicode::UTF8::encode_utf8($str)
    );
}

encode より decode のが差が大きい感じ。encode だけだと、文字列長くなると Encode の方が速いっぽい。


【2013/03/05 追記】 速さの謎について、@dankogai さんがエントリー書いてくれました。

答えは、 validation にあります。 decode では入力が正しい UTF-8 になっているかをいずれもチェックしていますが、Unicode::UTF8ではこの部分が最適化されています。その一方、Encodeでは他の文字コードとの共通APIのために余計なオーバーヘッドがあります。特に大きいのは PerlIO とのやりとりで、そのためのメソッド呼び出しが必ず一回以上発生します。

弾さんのエントリでは Unicode::UTF8 使いどころなさそうだね、ということになってるんですが、個人的には utf8::encode/utf8::decode の破壊的インターフェースが嫌い、というか使いにくいと感じているので、それ(特に decode の場面)の置き換えに Unicode::UTF8 良さそうだなという印象です。

まあ、こだわるほどクリティカルな場面というのがいまのところないので Encode で済ましてしまいますが。

サイト内検索