【问题标题】:How are associative arrays implemented in PHP?PHP 中的关联数组是如何实现的?
【发布时间】:2010-09-19 20:01:30
【问题描述】:

谁能解释一下 PHP 如何实现关联数组? PHP 使用什么底层数据结构? PHP是否对密钥进行哈希处理并将其存储在某种哈希映射中?我很好奇,因为我想知道关联数组在插入和搜索键时的性能如何。

【问题讨论】:

标签: php arrays php-internals


【解决方案1】:

最高投票的答案链接已损坏,并没有给出太多解释。

PHP 是用 C 语言编写的,底层结构只是一个 C 数组。 C 数组只是内存块。 C 数组中的索引必须是连续的,不能有索引 0 和后面的索引 1000。为了使关联数组键起作用,在将它们添加到 C 数组之前,它们会通过哈希函数转换为适当的 C 索引。

对于完整的解释,我发现这个链接提供了更多信息。

http://nikic.github.io/2012/03/28/Understanding-PHPs-internal-array-implementation.html

【讨论】:

  • 底层 C 数组的大小是多少?如果数组超时增长,大小是否增加并且键重新散列,例如在 Java 的 HashMap?谢谢!
  • @tonix 你可以自己查看源代码 - github.com/php/php-src/blob/master/Zend/zend_hash.c。它过去只是在 php5 中使用 HashTable 数据类型,但现在一切都是 zen 引擎,所以他们使用 zend_hash,它仍然使用哈希表。你可以阅读更多关于它的信息:phpinternalsbook.com/php5/hashtables.html
  • @tonix 简而言之,是的。与大多数哈希表一样,如果插入的元素将容器的负载因子增加到超出实现定义的阈值,则该表会为更大的数组分配内存并重新哈希键。
  • @CyRossignol 感谢您的回复!重新散列所有键听起来像是一个昂贵的 O(n) 操作。
  • @tonix 没错,这是一项相对昂贵的操作。大多数通用哈希表通过分配比一次插入所需的更大的数组来摊销此成本,以便后续插入不会产生开销。从算法分析的角度来看,插入成本接近 O(1)
【解决方案2】:

这是一个哈希表。类型声明和哈希函数在这里:
http://svn.php.net/viewvc/php/php-src/trunk/Zend/zend_hash.h?view=markup

在spl(标准php lib)中有一个轻量级数组和一个链表

【讨论】:

【解决方案3】:

好吧,无论如何,所有 PHP 数组都是关联数组。

【讨论】:

    【解决方案4】:

    @EBGreen 是正确的。

    这会给您带来一些有趣的性能问题,尤其是在将数组视为列表并使用 [](数组添加)运算符时。 PHP 似乎没有缓存最大的数字键并向其添加一个,而是似乎遍历所有键以查找下一个数字键应该是什么。由于 PHP 的 array-as-a-list 性能不佳,我用 python 重写了脚本。

    关联数组具有标准的 dict/hash 性能开销。

    【讨论】:

    • 你确定吗?我刚刚在一个包含 1000 个条目的测试数组上运行了基准测试(一个接一个地复制到一个新数组),如果你没有为新数组指定键,它总是快 7%(在 PHP 5.2.6 )
    • 他们最近可能更改了它。我在做这项工作时使用的是 5.1。当您谈论 10k 或更多条目时,PHP 的数组是 AWFUL。
    • @RickyMason。通常情况下您可能不会,但为了进行彻底的测试,计算 10、100、1k 和 10k 的每个项目时间会真正突出可伸缩性性能问题,尤其是在可能必须处理 10k 的情况下。
    【解决方案5】:

    根据各种网络论坛的消息来源,这都是哈希表: http://www.usenet-forums.com/php-language/15348-zend-engine-array-implementation.html

    如果您想确定,请阅读源代码,然后编译它,但请确保您可以trust your compiler(警告:PDF,不相关,但非常酷)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 2017-08-30
      • 2016-01-28
      • 2023-03-27
      • 2018-03-28
      • 1970-01-01
      • 2012-06-10
      相关资源
      最近更新 更多