WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:Perlで1バイト単位の処理

0:[投稿] 29歳からのPerl [2002/09/13 02:51 ][環境:WIN+IE UNIX系+Perl]

質問させてください。

Perlで、文字列の先頭から1バイト単位で処理をしていきたいのですが、
どのような方法が一番高速に処理できるのでしょうか?
substrで1バイトずつ取り出していたら、オーバーヘッドが大きそうに思えます。
Cのポインタのようなものはありませんか?

よろしくお願いします。


1:[回答] ふじ [URL] [2002/09/13 04:46 ]

> どのような方法が一番高速に処理できるのでしょうか?
では、どのような方法を思いつきましたか?
思いついたものでベンチマークを取れば、速いのがどれか分かると思いますが。


とりあえず、

・ split で分割
foreach my $x(split //, $str){                                                                                      
   do_something($x);                                                                                              
}
                                                               

・ 正規表現で1バイトづつ処理
$str =~ s/(.)/do_something($1)/egs;

・ substrで1バイトづつ取り出す
for (my $i = 0; $i < length($str); $i++){                                                                          
   $x = substr($str, $i, 1);                                                                                      
   do_something($x);                                                                                              
}

で、ベンチマークを取ってみました。
ベンチマークスクリプトは
http://sake-nikki.dyndns.org/~fujiwara/bench/strbench.pl
に置いておきます。

Perl-5.6.0 (Linux) での結果。
1. $str が 1KB の場合

regexp:  3 wallclock secs ( 3.24 usr +  0.00 sys =  3.24 CPU) @ 166.05/s (n=538)
split:  3 wallclock secs ( 3.10 usr +  0.00 sys =  3.10 CPU) @ 298.39/s (n=925)
substr:  3 wallclock secs ( 3.24 usr +  0.00 sys =  3.24 CPU) @ 229.94/s (n=745)

2. $str が 1MB の場合
regexp: 25 wallclock secs (25.30 usr +  0.11 sys = 25.41 CPU) @  0.16/s (n=4)
split: 15 wallclock secs (14.37 usr +  0.20 sys = 14.57 CPU) @  0.27/s (n=4)
substr: 18 wallclock secs (18.04 usr +  0.00 sys = 18.04 CPU) @  0.22/s (n=4)

・Perl-5.8.0 (Linux) での結果。
1. 1KB
regexp:  3 wallclock secs ( 3.17 usr +  0.00 sys =  3.17 CPU) @ 164.35/s (n=521)
split:  3 wallclock secs ( 3.18 usr +  0.00 sys =  3.18 CPU) @ 327.99/s (n=1043)
substr:  3 wallclock secs ( 3.20 usr +  0.00 sys =  3.20 CPU) @ 412.19/s (n=1319)

2. 1MB
regexp: 27 wallclock secs (26.81 usr +  0.45 sys = 27.26 CPU) @  0.15/s (n=4)
split: 14 wallclock secs (13.82 usr +  0.08 sys = 13.90 CPU) @  0.29/s (n=4)
substr: 10 wallclock secs ( 9.81 usr +  0.00 sys =  9.81 CPU) @  0.41/s (n=4)


Perl5.6 だと split が、Perl5.8 だと substr が高速なようです。

もっとも、本当に高速に処理する必要があって、かつ C が使えるのであれば、
Inline::C や XS を使って、1バイトづつ処理する部分を C で実装してしまう
のがいいかもしれません。
1バイト取り出した後の処理に Perl でやりたいことがあるならダメですけど。


2:[完了] 29歳からのPerl [2002/09/14 22:14 ]

ふじさん、ありがとうございました。

自分で思いついた方法は、substrとsplitだけだったんですが、
文字列処理の一文字取り出しに関数を呼び出すのに抵抗があったんです。
splitの方法は、メモリも食いそうで問題外な感じだったんですが、
意外と速い(?)んですね。驚きました。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World