与对 C 程序的系统调用相比,perl 删除非 ascii 字符太慢
perl remove non ascii chars too slow compared to system call to C program
我有一个用于删除非 ascii 字符和 ^M 的 perl 代码
但是对于 1.5GB 的文件,这需要 14 分钟(在 Linux 64 位、16GB RAM、LANG=C 设置上)
我刚刚用 C 重写了相同的逻辑,现在用 perl 进行系统调用
这只需要 36 秒(同一台机器,同一文件)
为什么这个 perl 代码很慢(我试图复制项目的一小部分)。与下面的 C 程序相比,它花费了 30 倍的时间
PERL
my $newfile = $ARGV[0] . ".cleaned";
open(IN,$ARGV[0]) || die "Could not open file $ARGV[0] $!";
open(OUT,">$newfile");
while(defined($c = getc(IN))){
next if((($i =ord($c)) > 126) || ($i == 13 ));
print OUT $c;
}
close IN;
rename($newfile,$ARGV[0]);
C
#include <stdio.h>
int main(int argc, char **argv){
char tmpfile[200];
FILE *fin,*fout;
int c;
snprintf(tmpfile,180,"%s.cleaned",argv[1]);
fin = fopen(argv[1], "rb");
fout = fopen(tmpfile, "w");
while ((c = fgetc(fin)) != EOF) {
if (c==13 || c > 126) continue;
fputc(c, fout);
}
fclose(fin);
fclose(fout);
rename(tmpfile,argv[1]);
return 0;
}
读取 1M 块并使用 tr///
翻译应该比当时读取一个字节执行得更快,
perl -i -pe 'BEGIN{ $/ = 24**2 } tr|\r\x7F-\xFF||d' file
如果问题是"why it happens",那只是因为C的运行水平低于Perl,而且以效率着称。对于相同的任务,C 几乎总是(我猜)会更快。
我有一个用于删除非 ascii 字符和 ^M 的 perl 代码 但是对于 1.5GB 的文件,这需要 14 分钟(在 Linux 64 位、16GB RAM、LANG=C 设置上)
我刚刚用 C 重写了相同的逻辑,现在用 perl 进行系统调用 这只需要 36 秒(同一台机器,同一文件)
为什么这个 perl 代码很慢(我试图复制项目的一小部分)。与下面的 C 程序相比,它花费了 30 倍的时间
PERL
my $newfile = $ARGV[0] . ".cleaned";
open(IN,$ARGV[0]) || die "Could not open file $ARGV[0] $!";
open(OUT,">$newfile");
while(defined($c = getc(IN))){
next if((($i =ord($c)) > 126) || ($i == 13 ));
print OUT $c;
}
close IN;
rename($newfile,$ARGV[0]);
C
#include <stdio.h>
int main(int argc, char **argv){
char tmpfile[200];
FILE *fin,*fout;
int c;
snprintf(tmpfile,180,"%s.cleaned",argv[1]);
fin = fopen(argv[1], "rb");
fout = fopen(tmpfile, "w");
while ((c = fgetc(fin)) != EOF) {
if (c==13 || c > 126) continue;
fputc(c, fout);
}
fclose(fin);
fclose(fout);
rename(tmpfile,argv[1]);
return 0;
}
读取 1M 块并使用 tr///
翻译应该比当时读取一个字节执行得更快,
perl -i -pe 'BEGIN{ $/ = 24**2 } tr|\r\x7F-\xFF||d' file
如果问题是"why it happens",那只是因为C的运行水平低于Perl,而且以效率着称。对于相同的任务,C 几乎总是(我猜)会更快。