我有一个网络守护程序,它在 TCP 套接字上接收固定长度(44 字节)的消息。
我正在尝试确定我应该使用 sysread 读取的最佳字节长度是多少。我当然可以做一个 sysread 44 字节的循环,但我想提出一个最佳大小。
我可以看到一个优势,而不是说,一个兆字节的数据来做 substr ,但我也可以看到为什么做一千个 sysread 调用会导致缓慢。
在公共互联网上进行 sysreads 是否有合适的大小推荐?
编辑:脚本得到一堆 44 字节的消息,它们被排队。
越大越好!sysread
将在任何字节可用时立即返回。
由于您永远无法保证收到完整的消息,并且您永远无法保证不会收到超过一条消息,因此您需要在 Perl 端有一个循环。由于您在 Perl 端已经有一个循环,因此您不妨一次性从系统中获取尽可能多的数据,以避免不必要的系统调用。
use constant READ_SIZE => 65*1024;
my $buf = '';
while (1) {
my $rv = sysread($fh, $buf, READ_SIZE, length($buf));
die if !defined($rv);
last if !$rv;
while ($buf =~ s/^(.{44})//s) {
my $msg = $1;
process_msg($msg);
}
}
选择一个尺寸和显示器$buf
的尺寸。如果它经常接近READ_SIZE
,增加READ_SIZE
。
我不确定开销是多少,只有你可以衡量一个是否比另一个快,但如果我要尝试从晴朗的蓝天中选择一个大小,我会先使用4092
字节。这使您最多可以处理 93 条消息,并且它在神奇的 4Kb 大小之下,这听起来是一个不错的起点。
您可以在程序运行的系统上找出页面大小,并进行相应调整。我会先int(PAGE_SIZE / MESSAGE_SIZE)
看看每条消息的性能是否优于一个sysread
。
另一方面,perl
默认使用 8KB 缓冲区:
192 /* The default buffer size for the perlio buffering layer */
193 #ifndef PERLIOBUF_DEFAULT_BUFSIZ
194 #define PERLIOBUF_DEFAULT_BUFSIZ (BUFSIZ > 8192 ? BUFSIZ : 8192)
195 #endif
您可能还会发现导致更改信息的讨论。
系统调用不会复制未传输的字节。如果你有一个 44 字节的消息 perl 将总是返回一个 44 字节的字符串。您提供的大小只是一个最大值,用于确定提供给内核的缓冲区大小。提供超过 44 个字节的价值在于,如果排队的消息不止一条,您将在一个系统调用中将它们全部获取。