在PHP中,数组查找速度如何?长缓存键

3
我正在研究一种方法,由于其操作的昂贵性和以相同参数调用的频率,缓存返回值将会有益处。
我将使用 serialize() 将参数序列化为缓存键,但这可能会导致非常长的键,因为数组参数很长。
以下是需要翻译的问题:
1. PHP 数组索引和查找是否会受到如此长的键(从 250B 到 1kB+)的影响? 2. 到目前为止还不错,但我是否面临着在某些时候可能会惨败的情况? 3. 基本上,我应该对键进行 md5()(或替代)吗?
小澄清: 这只是每个请求的缓存,没有永久存储。所讨论的方法是视图助手的方法,在每个视图生成中它可能会被调用500次或更多。

用MD5而不是序列化,有点奇怪。 - Hans Wassink
@Hans Wassink - 我想说的是将serialize()的结果进行md5()处理。 - Dan Lugg
无论如何,向fyr致敬:D - Hans Wassink
2个回答

4
你应该一定要对密钥进行哈希。你可能会问:“为什么我要冒着发生碰撞的风险,而不是在每个时间点都连接一个唯一的密钥?”简单的答案是,如果你通过字符串连接生成缓存键,你必须始终计算空间需求的最坏情况以估算内存使用情况。
因此,如果你有一个带有200个条目的缓存,并且有两个最大长度为20个字符的字段。最坏情况将是200*2*20*(字符大小)。如果你在每个可能的并行连接上加载完整的缓存,这将乘以并行连接的数量。
使用哈希,你总是具有最小的内存需求=密钥字段的最大内存需求。
如果你有许多值被连接用于密钥,那么它的扩展性将非常糟糕。
编辑:
即使你按请求使用它,数组也会占用内存。虽然它是缓存,但它从请求的开始到结束都存在。因此,你需要考虑它在内存中消耗了一定量的空间,而使用哈希则是固定的量。
第二件事是需要比较密钥。如果你使用字符串密钥访问关联数组,则解释器需要逐个字符地比较密钥。如果你有用于生成密钥的哈希方法,则这也将是固定数量的步骤。
如果你使用连接,步骤的数量将在最佳情况和最坏情况之间变化。

感谢@fyr - 根据我的澄清,此缓存没有永久存储,因为它是每个请求的。无论如何,我的键往往变得非常庞大,从低端的30B到高达1kB+;我正在使用一个6参数函数进行serialize(func_get_args()),其中3个通常是深度数组。我会对其进行基准测试,但为了在调试转储时保留内存并提高可读性,我认为我会选择哈希。 - Dan Lugg

1

通常不会使用如此长的数组键,但您可能需要进行基准测试来猜测它实际上会导致多少减速。如果有疑问,只需对其进行md5加密-根据您所说的,与md5时间相比,加速仍然会很大,后者将是微不足道的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接