PHP 中是不是有除数组之外的其他数据结构,我可以从不同的索引技术中受益吗?
Posted
技术标签:
【中文标题】PHP 中是不是有除数组之外的其他数据结构,我可以从不同的索引技术中受益吗?【英文标题】:Are there alternative data structures than array in PHP, where I can benefit from different index techniques?PHP 中是否有除数组之外的其他数据结构,我可以从不同的索引技术中受益吗? 【发布时间】:2012-01-21 15:56:31 【问题描述】:最近我遇到了一个包含数十万个值的数组的问题,我唯一想做的就是检查一个值是否已经存在。 就我而言,这是来自网络服务器日志的 IP。 所以基本上是这样的:
in_array(ip2long(ip),$myarray)
完成了这项工作
但是查找时间急剧增加,10k 次查找大约需要 17 秒左右。
所以在这种情况下,我不在乎是否有重复,我只需要检查是否存在。所以我可以像这样将 IP 存储在索引中:
isset($myarray[ip2long($ip)])
而且,对于 10k 次查找,查找时间从 17 秒(甚至更多)下降到 0.8 秒的静态时间。作为数组条目的值,我刚刚使用了int 1
。
我认为数组索引可能基于一些 b-tree,它应该具有 log(n) 查找时间和 hashmap 上的索引。
在我的情况下,使用索引工作得很好,但是是否有任何数据结构可以使用哈希图作为值索引,其中也可能出现多个值(我意识到这只有在没有太多重复项和我不能有效地使用范围/搜索请求,这是树结构的主要好处)?
【问题讨论】:
【参考方案1】:在与 php 捆绑的SPL library 中,除了简单数组之外,还有一系列替代数据结构,包括链表、堆栈、堆、队列等。
但是,我怀疑如果您 flipped 您的数组,您可以使您的逻辑更加高效,允许您查找键(使用 array_key_exists() 函数)而不是搜索值。数组索引是一个散列,而不是一个 btree,使得通过键可以非常快速地直接访问。
但是,如果您正在处理一个数组中的 10k 个条目,您可能会更好地利用数据库,您可以在其中定义自己的索引。
【讨论】:
有时好的解决方案就在你面前,你只是想得太复杂了。 -- 做得很好。 他根据我的理解翻转了它。 使用 isset($a[$key]) 比使用 array_key_exists($key, $a) 快很多 (!),因为 isset 是一个结构体,而 array_key_exists() 是一个函数。【参考方案2】:您还拥有chdb(常量哈希数据库)扩展 - 这非常适合。
【讨论】:
【参考方案3】:数组具有顺序,并且可以快速访问某些元素,因为您不需要遍历树或通过顺序列表结构工作。
这里的集合当然更快,因为您只检查唯一元素而不是所有元素(在数组中)。
树适用于示例排序结构。您可以使用按范围排序的 IP 实现一棵树,然后您可以更快地确定该 IP 是否存在。 我不确定 PHP 是否提供了这种自定义的树结构。我想你需要自己实现这个,但这大约需要半个小时。
您可以在网络上找到此类树结构的示例代码。
【讨论】:
【参考方案4】:正如已经回答的那样,您可以使用 spl http://www.php.net/spl 提供的全新课程
但显然它们并没有人们想象的那么快。可能它们没有像我们预期的那样实施。我认为例如 splfixedarray 不是真正的数组,而是作为经典 php 数组的哈希表
但是,您还有一些替代解决方案
首先,您可以将结果存储在数据库中。查询速度很快,因为 db 索引可能比 php 数据结构更优化
您可以使用http://www.php.net/sqlite3 并将结果存储在临时数据库(文件或内存中)
我建议一个临时文件,因为您不必将所有内容都加载到内存中,而且您可以单独添加每一行(例如使用http://www.php.net/fgets)
HTH!
请随时纠正我的英语
【讨论】:
以上是关于PHP 中是不是有除数组之外的其他数据结构,我可以从不同的索引技术中受益吗?的主要内容,如果未能解决你的问题,请参考以下文章
如果有除使用 kSystemSoundID_Vibrate 之外的其他振动方法
HTML onSubmit / onClick 处理函数可以有除事件之外的另一个参数吗? [复制]