PHP 中数组使用起来非常的方便,可以使用字符串或者其他的复合类型作为数组的键。

我们知道数据都是存储在某个存储器地址上,在 C 语言中数组就只支持数字类型的下标来方便寻找元素。

使用了这么长时间的 PHP 语言,你是否对 PHP 数组的实现方式感兴趣呢?使用了什么数据结构?

介绍

PHP 数组的底层实现使用了 HashTable 这种数据结构。

HasahTable 又叫做散列表,具有如下特点

  • 以 O(1) 的效率执行插入、删除和查找操作
  • 元素是 K-V 形式存储,元素间是无顺序结构不能对数据进行排序

源码版本: php-7.1.19-src

解决哈希冲突一般有两种方式,PHP 使用的是分离链接法,既当产生冲突时,数据形成一个链表。

Hashtable 的数据结构

 typedef struct _Bucket {
zval val; /* 存储的具体数据 */
zend_ulong h; /* hash 值 */
zend_string *key; /* 字符串键 | null(数字键时) */
} Bucket; typedef struct _zend_array HashTable; struct _zend_array {
zend_refcounted_h gc;
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar flags,
zend_uchar nApplyCount,
zend_uchar nIteratorsCount,
zend_uchar consistency)
} v;
uint32_t flags;
} u;
uint32_t nTableMask; /* 掩码,用于根据hash值计算存储位置,永远等于nTableSize-1 */
Bucket *arData; /* 存放实际数据 */
uint32_t nNumUsed; /* arData数组已经使用的数量 */
uint32_t nNumOfElements; /* hash表中元素个数 */
uint32_t nTableSize; /* hash表的大小 */
uint32_t nInternalPointer; /* 用于HashTable遍历 */
zend_long nNextFreeElement; /* 下一个空闲可用位置的数字索引 */
dtor_func_t pDestructor; /* 析构函数 */
};

仔细观察上面的数据结构

  • _zend_array 就是 PHP 数组的 HashTable 结构,存储了 HashTable 的一些大小、元素多少等必要信息
  • 结构体 _Bucket (对应 _zend_array 中的 arData) 存储用户定义变量的数据,包括变量值和对应的键值

所以总结来说 PHP HashTable 的实现仍然使用的是数组这种数据结构(arData 是存储数据的数组),使用了一块连续的存储空间。如下图

PHP7 HashTable 的其他特点请阅读 Laruence 深入理解PHP7内核之HashTable

PHP 7中新的Hashtable实现和性能改进

PHP internals Book

PHP 哈希表(数组)的内核实现

PHP HashTable总结的更多相关文章

  1. HashSet HashTable 与 TreeSet

    HashSet<T>类 HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素. HashSet& ...

  2. Javascript实现HashTable类

    散列算法可以尽快在数据结构中找出指定的一个值,因为可以通过Hash算法求出值的所在位置,存储和插入的时候都按照Hash算法放到指定位置. <script> function HashTab ...

  3. Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结

    2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...

  4. java面试题——HashMap和Hashtable 的区别

    一.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Clonea ...

  5. Map集合及与Collection的区别、HashMap和HashTable的区别、Collections、

    特点:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值. Map集合和Collection集合的区别 Map集合:成对出现 (情侣)                       ...

  6. HashTable初次体验

    用惯了数组.ArryList,初次接触到HashTable.Dictionary这种字典储存对于我来说简直就是高大上. 1.到底什么是HashTable HashTable就是哈希表,和数组一样,是一 ...

  7. HashMap和 Hashtable的比较

    Hashtable 和 HashMap的比较 1.  HashMap可以接受null(HashMap可以接受为null的键值(key)和值(value), HashTable不可以接受为null的键( ...

  8. hashMap和hashTable的区别

    每日总结,每天进步一点点 hashMap和hashTable的区别 1.父类:hashMap=>AbstractMap hashTable=>Dictionary 2.性能:hashMap ...

  9. SortedList和HashTable

    都是集合类,C#中同属命名空间System.Collections,“用于处理和表现类似keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写:value用于存储对应于key的 ...

  10. Java Hashtable的实现

    先附源码: package java.util; import java.io.*; /** * This class implements a hash table, which maps keys ...

随机推荐

  1. bootstrap-multiselect.js多选下拉框初始化时默认选中初始值

    bootstrap-multiselect.js多选下拉框默认值设置 一.案例数据格式  二.HTML代码 <select id="msgRoles" multiple=&q ...

  2. Arcgis for Android 空间数据WKT与JSON描述

    点线面数据标准格式 一. 点 WKT: POINT(-118.4 -45.2) JSON: { "x": -118.4, "y": -45.2, "s ...

  3. codeforces 609E Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  4. POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环

    题目链接: https://cn.vjudge.net/problem/POJ-2886 题目大意: N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数 ...

  5. Django:ORM关系字段

    一,ForeignKey 外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方. ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系 ...

  6. BZOJ1123:[POI2008]BLO(双连通分量)

    Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n&l ...

  7. Java中Thread类的join方法到底是如何实现等待

    现在的场景是A线程执行:public void run(){ bThread.join(0);//把b线程加入到当前线程(a线程),等待b结束,当前a线程才会结束.}B线程执行public void ...

  8. Javascript中==和===的区别

     一.JavaScript"=="的作用 1.当==两边的内容是字符串时,则比较字符串的内容是否相等. 2.当==两边的内容是数字时,则比较数字的大小是否相等. 3.当==两边的内 ...

  9. Entity Framework 三

    DbContext:上下文 EDM将生成从System.Data.Entity.DbContext类派生的SchoolDBEntities类,如下所示.派生DbContext的类在实体框架中被称为上下 ...

  10. django-多表操作2

    #######多表操作二######## 昨天写了基于双下划线查找,都是两个表之间查找,那再多跨几个表呢?还是一样,一步一步分析 # 跨多表查询: 查询红楼梦这本书的作者的电话: (Author,Bo ...