<>运算符缓冲区大小

时间:2016-08-17 07:26:17

标签: perl buffer file-handling

我有一个包含很长行的文件需要处理,我发现这个过程卡住了/“非常慢”#39;因为缓冲区不够大或者由于处理很长的行可能需要一段时间。这是代码示例:

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);
}

线路处理不是&#34;重&#34;。

我找了一些东西来解决它并遇到了PerlIO::buffersize但看起来它现在还没有维持一段时间而且我不想使用版本为0.001的模块。如何修改<>运算符缓冲区大小?或者,有没有办法在用<>读取它之前知道行长度?

3 个答案:

答案 0 :(得分:3)

您可能需要的是:

ClickDismissOnJsAlert(); element.Click() - 可以设置为数值,用于从文件中读取的字节数。

  

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

来源:perlvar

答案 1 :(得分:3)

更改Perl的读取缓冲区大小不太可能对程序的速度产生任何显着影响,并且您看到的影响更可能是因为磁盘驱动器本身的读取时间较长。在 perlmonks.org

上查看Perl Read-Ahead I/O Buffering

此外,使用read或将记录分隔符$/设置为固定大小来实现自己的缓冲,很可能会减慢您的程序速度,因为您仍需要将所拥有的内容分开读入数据行,但现在必须在Perl代码中执行,而不是让perl在C中为您执行此操作

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

答案 2 :(得分:1)

  

如何修改<>运算符缓冲区大小?

<>读入可以增长到任何大小的标量,所以我认为你指的是传递给read系统调用的缓冲区的大小。

在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

只能在构建perl时使用以下命令配置

./Configure -Accflags=-DPERLIOBUF_DEFAULT_BUFSIZ=8192

这适用于所有缓冲的阅读功能,包括readreadline<>是别名),readpipeeof,但不是sysread

请注意,将$/设置为对数字的引用会导致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

如果您确实要执行单个read系统调用,则需要使用sysread

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