【问题标题】:Perl: string length limitations in real lifePerl:现实生活中的字符串长度限制
【发布时间】:2014-05-14 03:42:32
【问题描述】:

虽然,例如,perldata 文档在 Perl 中标量字符串仅受可用内存限制,但我强烈怀疑在现实生活中还会存在一些其他限制。

我正在考虑以下想法:

  • 我不确定 Perl 中的字符串是如何实现的——是否有某种字节/字符计数器?如果有,那么它可能被实现为与平台相关的整数(即 32 位或 64 位),因此有效地将字符串限制为 2 ** 312 ** 322 ** 632 ** 64 字节.
  • 如果 Perl 不使用计数器而是使用一些字节来终止字符串(这很奇怪,因为在 Perl 中可以使用像 "foo\0bar" 这样的字符串),那么所有操作都将不可避免地得到随着字符串长度的增加,速度要慢得多。
  • Perl 处理字符串的大多数字符串函数,例如length,都返回正常的标量整数,我强烈怀疑它也会是受平台限制的整数。

那么,在现实生活中限制 Perl 字符串长度的其他因素是什么?出于实际目的,什么应该被认为是合适的字符串长度?

【问题讨论】:

  • perl -E '$x = "x" x (2 ** 31); $y = $x x 7;say length $y' 为我返回 15032385536,但 $x x 8 段错误。我有 16 GB,ptrsize=8
  • 关于第一点:有多少64位机器有超过2^64字节的内存?

标签: string perl limit


【解决方案1】:

它跟踪缓冲区的大小和其中的字节数。

$ perl -MDevel::Peek -e'$x="abcdefghij"; Dump($x);'
SV = PV(0x9222b00) at 0x9222678
  REFCNT = 1
  FLAGS = (POK,pPOK)
  PV = 0x9238220 "abcdefghij"\0
  CUR = 10                        <-- 10 bytes used
  LEN = 12                        <-- 12 bytes allocated
  • 在 32 位 Perl 构建中,它使用 32 位无符号整数来表示这些值。这(完全)足够大,可以创建一个用完进程的整个 4 GiB 地址空间的字符串。

  • 在 Perl 的 64 位构建中,它使用 64 位无符号整数来表示这些值。这(正好)足够大,可以创建一个字符串,用完您的进程的整个 16 个EiB 地址空间。

文档是正确的。字符串的大小仅受可用内存的限制。

【讨论】:

  • 从技术上讲,我可以使用设置 Perl(带有构建时选项)在 64 位平台上使用 32 位整数。因此,虽然在 64 位平台上运行(有 >4 GiB 的可用内存和巨大的地址空间),我仍然会被限制为 4 GiB?
  • 请注意我的回答中缺少单词平台。如果您在 32 位环境中运行程序,那么您是否拥有 64 位平台并不重要。如果您在 64 位平台上运行 32 位构建,则 32 位整数仍然足够大,可以处理所有进程的 4GB 地址空间。字符串的大小仅受可用内存的限制:4GB,减去操作系统保留的内存,减去已经用完的内存。
  • 我不是在谈论 32 位构建(即当 file 报告 ELF 32-bit LSB executable 时),我在谈论 64 位构建,但使用诸如 @987654325 之类的内置参数@ 或 ptrsize(我不确定在标量使用中使用什么 CURLEN)设置为 4 而不是 8。从技术上讲,这个二进制文件有超过 4 GiB 可用,但我强烈怀疑它会是只能处理 4 GiB 的字符串。
  • 这不可能。根据定义,64 位构建具有 64 位指针 (ptrsize=8),并且 Perl 整数保证足够大以容纳指针 (ivsize>=ptrsize)。就像我已经说过的,64 位构建使用 64 位整数来表示 CUR 和 LEN。
  • 理论上它可以为 CUR 和 LEN 使用更大的数字,但不能更小。
猜你喜欢
  • 1970-01-01
  • 2017-11-12
  • 2011-01-09
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多