我有一个包含很长行的文件需要处理,我发现这个过程卡住了/“非常慢”#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的模块。如何修改<>
运算符缓冲区大小?或者,有没有办法在用<>
读取它之前知道行长度?
答案 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
这适用于所有缓冲的阅读功能,包括read
,readline
(<>
是别名),readpipe
和eof
,但不是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