【发布时间】:2016-04-17 13:28:25
【问题描述】:
perl 中的基本类型与大多数语言不同,类型为标量、数组、散列(但显然不是子例程,&,我猜这实际上只是带有句法糖的标量引用)。最奇怪的是,最常见的数据类型:int、boolean、char、string,都属于基本数据类型“标量”。似乎 perl 决定根据修改它的运算符将标量视为字符串、布尔值或数字,这意味着标量本身在保存时实际上并未定义为“int”或“String”。
这让我很好奇这些标量是如何“在后台”存储的,特别是关于它对效率的影响(是的,我知道脚本语言会为了灵活性而牺牲效率,但它们仍然需要尽可能优化灵活性问题不受影响)。存储数字 65535(占用两个字节)然后存储占用 6 个字节的字符串“65535”对我来说要容易得多,因此认识到 $val = 65535 正在存储一个 int 将允许我使用 1/3 的内存,在大型数组中,这也可能意味着更少的缓存命中。
当然不仅限于节省内存。如果我知道预期的标量类型,有时我可以提供更重要的优化。例如,如果我有一个使用非常大的整数作为键的散列,如果我将键识别为整数,那么查找一个值会快得多,允许一个简单的模数来创建我的散列键,然后如果我必须运行更复杂的散列具有 3 倍字节的字符串的逻辑。
所以我想知道 perl 如何在后台处理这些标量。它是否将每个值都存储为字符串,在标量始终用作 int 的情况下,牺牲了将字符串常量转换为 int 的额外内存和 cpu 成本?或者它是否有一些逻辑来推断用于确定如何保存和操作它的标量类型?
编辑:
TJD 链接到 perlguts,它回答了我的一半问题。标量实际上存储为字符串、int(有符号、无符号、双精度)或指针。我并不太惊讶,我大多预计这种行为会发生在幕后,尽管看到确切的类型很有趣。不过,我将这个问题悬而未决,因为 perlguts 实际上是低级别的。除了告诉我存在 5 种数据类型之外,它没有指定 perl 如何在它们之间交替工作,即 perl 如何决定在保存标量时使用哪种 SV 类型以及它如何知道何时/如何转换。
【问题讨论】:
-
perlguts本身包含: 本文档试图描述如何使用 Perl API,并提供 一些 基本工作原理的信息Perl 核心。 它远未完成,可能包含许多错误。请向下面的作者提出任何问题或 cmets。 - 这个问题是相当合法的,应该作为一个世界评论更好地回答。 -
回复。您的编辑:每个运算符处理其操作数的方式不同。阅读完 perlguts 和 illguts 后,请查看 Perl 源代码中 pp_hot.c 中的一些操作码。 pp_add 很有趣,因为它尽可能地尝试进行整数加法,从而为每个操作数添加一个整数表示。即使您无法遵循代码,这些 cmets 也很有启发性:github.com/Perl/perl5/blob/blead/pp_hot.c#L641。另请查看 pp_print 和 pp_concat。
-
Re: Perl How Perl "alternates between them [types]", the camel book 在第 5 页给出了简洁的解释:“各种运算符期望某些类型的值作为参数,所以我们将讨论这些运算符作为“提供”或“提供”这些参数的标量上下文。有时我们会更具体,说它提供数字上下文、字符串上下文或布尔上下文……”。这意味着运算符没有重载,并且可以从 them 中唯一确定预期的类型。
标签: perl