PHP中用hash实现的数组_php技巧

PHP中使用最多的非Array莫属了,那Array是如何实现的?在PHP内部Array通过一个hashtable来实现,其中使用链接法解决hash冲突的问题,这样最坏情况下,查找Array元素的复杂度为O(N),最好则为1.
而其计算字符串hash值的方法如下,将源码摘出来以供查备:

复制代码 代码如下:

static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
{
register ulong hash = 5381;                                                   //此处初始值的设置有什么玄机么?
/* variant with the hash unrolled eight times */
for (; nKeyLength >= 8; nKeyLength -= 8) {                         //这种step=8的方式是为何?
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;                         //比直接*33要快
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
}
switch (nKeyLength) {
case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */                             //此处是将剩余的字符hash
case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */                    
case 1: hash = ((hash << 5) + hash) + *arKey++; break;
case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
}
return hash;//返回hash值
}

ps:对于以下函数,仍有两点不明:
hash = 5381设置的理由?
这种step=8的循环方式是为了效率么?

时间: 2024-07-29 22:50:44

PHP中用hash实现的数组_php技巧的相关文章

PHP以指定字段为索引返回数据库所取的数据数组_php技巧

很多情况下,我们从接触一个新的项目到开发完成,再回过头来仔细浏览一下自己写的代码,很多都是我们以前用熟练的代码.所以,在完成每个新项目的时 候,适当的做些项目总结.代码总结,或许你会在以后的项目中用得着,极有可能获得意外的收获,比如:代码优化,想到了更好.速度更快的实现方法等等. 牛逼的程序开发者有时候不在于代码量的多少,而是程序的代码简洁性.逻辑复杂但实现的方便性,这些才说明是否是一位好的程序员.我们不做日夜加班到深夜,拼代码量的程序员! 这篇和大家分享几个使用得PHP编程技巧,有些技巧是在看

php项目开发中用到的快速排序算法分析_php技巧

本文实例讲述了php项目开发中用到的快速排序算法.分享给大家供大家参考,具体如下: 实际上在,做web开发,比较少遇到使用一些算法之类的,毕竟不是做搜索引擎,也不是写底层(比如写个类似于mysql这样的数据库,里面需要自己实现排序算法),另外,每种语言,比如java,php都或多或少已经封装好排序函数给程序员使用.比如有个共识,大家做web开发的基本都明白,业务逻辑多比较简单,不是很复杂的业务逻辑.我们作为web开发的程序员,基本是是web架构,对数据库增删查改数据,然后把数据展示在页面中,大多

php将一维数组转换为每3个连续值组成的二维数组_php技巧

本文实例讲述了php实现将一维数组转换为每3个连续值组成的二维数组.分享给大家供大家参考,具体如下: <?php $aaa = array('aa','bb','cc','dd','ee','ff','gg','hh','ii'); for($i=0;$i<3;$i++) { $bbb[] = array_slice($aaa, $i * 3 ,3); } print_r($bbb); ?> 运行结果如下: Array ( [0] => Array ( [0] => aa [

PHP中的print_r 与 var_dump 输出数组_php技巧

print_r() 和 var_dump() 函数可以打印输出整个数组内容及结构. print_r() 利用 print_r() 函数可以打印输出整个数组内容及结构,按照一定格式显示键和元素.注意 print_r() 函数不仅是只用于打印,实际它是用于打印关于变量的易于理解的信息. 语法: bool print_r( mixed expression )例子: <?php $arr_age = array(18, 20, 25); print_r($arr_age); ?> 运行该例子输出:

PHP如何将XML转成数组_php技巧

如果你使用 curl 获取的 xml dataxml=simplexmlloadstring(data); data[′tk′]=jsondecode(jsonencode(xml),TRUE);如果是直接获取 URL 数据的话xml=simplexmlloadfile(data); data[′tk′]=jsondecode(jsonencode(xml),TRUE); 先把 simplexml 对象转换成 json,再将 json 转换成数组. 代码: <?php $string = <&

PHP随机生成唯一HASH值自定义函数_php技巧

网上有很多种方法获取随机唯一的HASH值,但是大同小异: 1.先获取随机的唯一字符串 2.进行MD5或者sha1算HASH值 一个项目要用到hash值,就去网上找了找,却发现PHP有一个函数能直接生成唯一字符串--uniqid(),通过使用这个函数,再加上自己生成的随机数(防止被破解),更具有唯一性且不易被猜解.主要考虑问题如下: 1.随机的效率与随机性:rand和mt_rand函数的选择,首选mt_rand,效率高,随机性好: 2.随机次数:选择5次,本来unniqid就是唯一的,加上随机的可

php数组函数序列之array_intersect() 返回两个或多个数组的交集数组_php技巧

array_intersect() 定义和用法 array_intersect() 函数返回两个或多个数组的交集数组. 结果数组包含了所有在被比较数组中,也同时出现在所有其他参数数组中的值,键名保留不变. 注释:仅有值用于比较. 语法 array_intersect(array1,array2,array3...) 参数 描述 array1 必需.与其他数组进行比较的第一个数组. array2 必需.与第一个数组进行比较的数组. array3 可选.与第一个数组进行比较的数组.可以有多个. 例子

PHP实现将textarea的值根据回车换行拆分至数组_php技巧

本文实例讲述了PHP实现将textarea的值根据回车换行拆分至数组的方法.分享给大家供大家参考.具体分析如下: textarea回车换行为 \r\n $keyword_list = trim($_REQUEST['keywords']); $keyword_arr = explode("\r\n", $keyword_list); 这个地方需要注意是要去除textarea 前后的空格,否则会多出一个 或者使用explode也是可以的 只是不能用\r\n只能用双引号,不能用单引号 希望

一个显示某段时间内每个月的方法 返回由这些月份组成的数组_php技巧

复制代码 代码如下: /** * 生成从开始月份到结束月份的月份数组 * 该方法仿照党子皓getDateArr()方法 * @param unknown_type $start * @param unknown_type $end */ function getMonthArr($start, $end) { $start = empty($start) ? date('Y-m',strtotime('-1 month')) : $start; $end = empty($end) ? date