Perl <&燃气轮机;操作员缓冲区大小

Perl <&燃气轮机;操作员缓冲区大小,perl,buffer,file-handling,Perl,Buffer,File Handling,我有一个文件有很长的行,我需要处理,我发现进程被卡住了/非常慢,因为缓冲区不够大,或者处理很长的行可能需要一段时间。下面是一个代码示例: open FH, "<$fname" or die "..."; while (<FH>) { my @arr = split //, $_; pop @arr; pop @arr; ... for some "limited small portion of the string length" number

我有一个文件有很长的行,我需要处理,我发现进程被卡住了/非常慢,因为缓冲区不够大,或者处理很长的行可能需要一段时间。下面是一个代码示例:

open FH, "<$fname" or die "...";
while (<FH>) {
    my @arr = split //, $_;
    pop @arr;
    pop @arr;
    ... for some "limited small portion of the string length" number of times ...
    pop @arr;
    if ($arr[-1] eq '0') {
        print "done!\n";
        last;
    }
    push @big_arr, join('', @arr);
}

打开FH,“您可能需要的是:

$/
-可以设置为数值,以便从文件中读取一定数量的字节

将$/设置为整数引用、包含整数的标量或可转换为整数的标量将尝试读取记录而不是行,最大记录大小为引用的整数字符数


来源:

您可能需要的是:

$/
-可以设置为数值,以便从文件中读取一定数量的字节

将$/设置为整数引用、包含整数的标量或可转换为整数的标量将尝试读取记录而不是行,最大记录大小为引用的整数字符数


来源:

改变Perl的读取缓冲区大小不太可能对程序的速度产生任何显著的影响,而您看到的影响更可能是从磁盘驱动器本身读取时间过长的结果。请查看perlmonks.org

此外,通过使用
read
或将记录分隔符
$/
设置为固定大小来实现您自己的缓冲,很可能会降低程序的速度,因为您仍然需要将读取的内容分离到数据行中,但现在必须在Perl代码中执行,而不是让Perl在C中为您执行


还请注意,将
$/
更改为固定记录大小的措施仍将使用Perl的标准(可能是8KB)缓冲区。唯一的区别是,返回给您的数据量将根据字节计数而不是分隔符字符串的位置来确定。更改Perl的读取缓冲区大小不太可能成功e您的程序速度有任何显著差异,您看到的影响更可能是由于从磁盘驱动器本身读取的时间较长。请查看perlmonks.org

此外,通过使用
read
或将记录分隔符
$/
设置为固定大小来实现您自己的缓冲,很可能会降低程序的速度,因为您仍然需要将读取的内容分离到数据行中,但现在必须在Perl代码中执行,而不是让Perl在C中为您执行

还请注意,将
$/
更改为固定记录大小的方法仍将使用Perl的标准(可能是8KB)缓冲区。唯一的区别是,返回给您的数据量将根据字节计数而不是分隔符字符串的位置来确定

如何修改操作员缓冲区大小

读入一个可以增长到任何大小的标量,因此我认为您指的是传递给
读取
系统调用的缓冲区大小

在5.14之前,Perl从4 KiB块中的文件句柄读取数据。5.14使其可配置,默认值为8 KiB

$ perl -e'print("x" x 9_999, "\n") for 1..2' >large_lines

$ strace 5.10.1t/bin/perl -e'my $line = <>' large_lines 2>&1 | grep read.*xxx
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 4096) = 4096
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 4096) = 4096
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 4096) = 4096

$ strace 5.14.2t/bin/perl -e'my $line = <>' large_lines 2>&1 | grep read.*xxx
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
这适用于所有缓冲读取功能,包括
read
readline
(其中
是别名)、
readpipe
eof
,但不包括
sysread

$ strace perl -e'sysread(STDIN, $buf, 8193)' <large_lines 2>&1 | grep read.*xxx
read(0, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8193) = 8193

请注意,将
$/
设置为对某个数字的引用将导致
readline
)充当
read
,该值仍处于缓冲状态

$ strace perl -e'$/ = \8193; my $block = <>' large_lines 2>&1 | grep read.*xxx
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
如何修改操作员缓冲区大小

读入一个可以增长到任何大小的标量,因此我认为您指的是传递给
读取
系统调用的缓冲区大小

在5.14之前,Perl从4 KiB块中的文件句柄读取数据。5.14使其可配置,默认值为8 KiB

$ perl -e'print("x" x 9_999, "\n") for 1..2' >large_lines

$ strace 5.10.1t/bin/perl -e'my $line = <>' large_lines 2>&1 | grep read.*xxx
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 4096) = 4096
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 4096) = 4096
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 4096) = 4096

$ strace 5.14.2t/bin/perl -e'my $line = <>' large_lines 2>&1 | grep read.*xxx
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
这适用于所有缓冲读取功能,包括
read
readline
(其中
是别名)、
readpipe
eof
,但不包括
sysread

$ strace perl -e'sysread(STDIN, $buf, 8193)' <large_lines 2>&1 | grep read.*xxx
read(0, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8193) = 8193

请注意,将
$/
设置为对某个数字的引用将导致
readline
)充当
read
,该值仍处于缓冲状态

$ strace perl -e'$/ = \8193; my $block = <>' large_lines 2>&1 | grep read.*xxx
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192
read(3, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"..., 8192) = 8192

当然,您也可以将
$/
设置为一个数字值,以便读取一定数量的字节。您可以转到低于
readline
)的级别,然后使用
read
。这也可能有帮助。@yon100:请告诉我们“非常长的行”的长度以及文件的总大小。
my@arr=split/,$\在字符串中一次迭代一个字符,所以是的,使用长行需要一段时间。这就是为什么;你找错树了!我认为你应该发布一个新问题,并解释你试图解决的实际问题,包括输入和输出示例。显示您当前的解决方案并解释您的性能要求,例如,“我想在30秒内处理一行20MB的文件。”您还可以将
$/
设置为一个数字值,以读取一定数量的字节。您可以转到低于
readline
)的级别,然后使用
read
。也可能有帮助。@yon100:请告诉我们“非常长的行”的长度和文件的总大小。
my@arr=split/,$\在字符串中一次迭代一个字符,所以是的,使用长行需要一段时间。这就是为什么;你找错树了!我认为你应该发布一个新问题,并解释你试图解决的实际问题,包括输入和输出示例。显示您当前的解决方案并解释您的性能要求,例如,“我想在30秒内处理一行20MB文件