在perl.哈希如何在内存中存储数据

use*_*517 4 perl

我有一个大的xml文件,解析它消耗了大量的内存.
因为我相信大部分是由于文件中有很多用户名.
我将每个用户名的长度从~28个字节更改为10个字节.
并再次运行.但它仍然需要几乎相同的内存量.
到目前为止,xml文件是用SAX解析的,在处理过程中,结果存储在一个哈希结构中,如下所示:
$this->{'date'}->{'school 1'}->{$class}->{$student}...

在减少学生姓名的长度后,为什么记忆仍然如此?是否可以将数据存储在哈希存储器中.无论字符串的长度是多少,都会有很多开销?

Gre*_*con 5

Perl哈希使用称为桶链的技术.具有相同的散列(查看宏的所有键PERL_HASH_INTERNALhv.h)走在相同的"桶",一个线性表.

根据perldata文档

如果在标量上下文中计算哈希值,则在哈希值为空时返回false.如果有任何键/值对,则返回true; 更准确地说,返回的值是一个字符串,由使用的桶数和分配的桶数组成,用斜杠分隔.这非常有用,只是为了找出Perl的内部哈希算法是否在您的数据集上表现不佳.例如,你在哈希中粘贴10,000个东西,但是%HASH在标量上下文中进行评估显示"1/16",这意味着只触摸了16个桶中的一个,并且可能包含所有10,000个项目.这不应该发生.如果在标量上下文中评估绑定的哈希,则会导致致命错误,因为此存储桶使用信息当前不可用于绑定哈希.

要查看数据集是否具有病态分布,您可以检查标量上下文中的各个级别,例如,

print scalar(%$this), "\n",
      scalar(%{ $this->{date} }), "\n",
      scalar(%{ $this->{date}{"school 1"} }), "\n",
      ...
Run Code Online (Sandbox Code Playgroud)

有关过时的概述,请参阅perl.com上Hashes真正起作用的方式.

学生姓名长度的适度减少,四级关键,不会产生显着差异.通常,perl实现强烈倾向于在问题上抛出内存.这不是你父亲的FORTRAN.