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 处理函数可以有除事件之外的另一个参数吗? [复制]

PHP相交与MySQL相交

除了使用字符串文字之外,还有其他方法可以在 C 中指定或输入 Unicode 代码点吗?

求一个PHP计算数组内元素的不同组合,请看案例

任务一 需求分析