ErlangとPerlの速度比較 その2
ErlangとPerlの速度比較の文字コード変換部分に関して,
Danさんからトラックバックをいただいたので再度測定してみた.
use utf8 は罠がいっぱいな割にメリットが少なく,普段は使用しないので・・・. (DBIが未対応だったり,モジュールによってフラグの扱いが違ったり(YAML::*とか)なので)
また,多くの場合は,ファイルやソケット等からUTF8バイト列を受け取って,それを利用することになるので, utf8フラグ無しの文字列からの変換で比較する方が実際の利用状況からもフェアではないかと感じるけれども.
(ただ,バイト列にしたとしても,やっぱりEncodeが一番速かった)
そんなわけで,コードは以下のように修正.
これで測定してみると・・・劇的に速くなった!
今までのpodにはfind_encodingのこのような使い方が載っていなかったので,from_toを使って遅いと思っている人は多そう. ここまで速いとは知らなかった.
エンコード名を探す(?)処理などで時間がかかっているのだろうか. (Encodeがサポートするエンコード名は山ほどあるし)
文字列が短いせいか,Danさんの結果より差が大きい.
そして,UniJPが遅い...(^^;
Erlangに比較しても,やはり文字列処理はPerlが得意,というのを実感.(正規表現も速いし)
Erlangの方も速くできないかと,ロックレベルを細かくすることでsmpで性能を向上させるべく, とりあえずソースに
を追加したら,動かなくなってしまった.
やはりそんな簡単にはいかない模様.
ドライバのマニュアルを読んでいたら,
なんて記述を発見.
iconvドライバはコレを使っていないので,controlを使う方法で呼び出せば,さらに高速化が可能かも.
時間が出来たらチャレンジしてみよう・・・
そもそもはじめからUTF-8、それもutf8フラグがたっている文字列にfrom_toを使うのはばかげている。とのことだけど,utf8フラグは立っていない想定.
use utf8 は罠がいっぱいな割にメリットが少なく,普段は使用しないので・・・. (DBIが未対応だったり,モジュールによってフラグの扱いが違ったり(YAML::*とか)なので)
また,多くの場合は,ファイルやソケット等からUTF8バイト列を受け取って,それを利用することになるので, utf8フラグ無しの文字列からの変換で比較する方が実際の利用状況からもフェアではないかと感じるけれども.
(ただ,バイト列にしたとしても,やっぱりEncodeが一番速かった)
そんなわけで,コードは以下のように修正.
my $dec = find_encoding("UTF-8"); my $enc = find_encoding("Shift_JIS"); my $str = "123あいう"; for(my $i = 0; $i < 0xffff; $i++) { $enc->encode($dec->decode($str)); }
これで測定してみると・・・劇的に速くなった!
今までのpodにはfind_encodingのこのような使い方が載っていなかったので,from_toを使って遅いと思っている人は多そう. ここまで速いとは知らなかった.
エンコード名を探す(?)処理などで時間がかかっているのだろうか. (Encodeがサポートするエンコード名は山ほどあるし)
方法 | 言語 | 時間(sec) |
---|---|---|
iconv | Erlang (beam) | 0.604394 |
Erlang (native) | 0.612490 | |
Erlang (beam+smp) | 1.232886 | |
Erlang (native+smp) | 1.250170 | |
Unicode::Japanese | Perl | 0.646837 |
Encode | Perl | 1.403991 |
Encode(改) | Perl | 0.151645 |
文字列が短いせいか,Danさんの結果より差が大きい.
そして,UniJPが遅い...(^^;
Erlangに比較しても,やはり文字列処理はPerlが得意,というのを実感.(正規表現も速いし)
Erlangの方も速くできないかと,ロックレベルを細かくすることでsmpで性能を向上させるべく, とりあえずソースに
driver_flags = ERL_DRV_FLAG_USE_PORT_LOCKING
を追加したら,動かなくなってしまった.
やはりそんな簡単にはいかない模様.
ドライバのマニュアルを読んでいたら,
int control(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen) This is a special routine invoked with the erlang function port_control/3. It works a little like an "ioctl" for erlang drivers. The data given to port_control/3 arrives in buf and len. The driver may send data back as a driver binary, using *rbuf and rlen. This is the fastest way of calling a driver and get a response. It won't make any context switch in the erlang emulator, and requires no message passing. It is suitable for calling C function to get faster execution, when erlang is too slow.
なんて記述を発見.
iconvドライバはコレを使っていないので,controlを使う方法で呼び出せば,さらに高速化が可能かも.
時間が出来たらチャレンジしてみよう・・・
The comments to this entry are closed.
Comments