在一个非常紧凑的循环中,我需要访问包含数百万个元素的数组中的数万个值。键可以是未定义的:在这种情况下,返回 NULL 而没有任何错误消息是合法的:
数组键存在:元素的返回值。数组键不存在:返回 null。
我确实知道多种解决方案:
if (isset($lookup_table[$key])) {
return $lookup_table[$key];
} else {
return;
}
或者
@return $lookup_table[$key];
或者
error_reporting(0);
$return = $lookup_table[$key];
error_reporting(E_ALL);
return $return;
所有解决方案都远非最佳:
- 第一个需要在 B-TREE 中进行 2 次查找:一个检查存在,另一个检索值。这有效地使运行时间加倍。
- 第二个使用错误抑制运算符,因此在该行上产生了巨大的开销。
- 第三个调用错误处理程序(它将检查 error_reporting 设置,然后不显示任何内容),从而产生开销。
我的问题是,如果我错过了一种避免错误处理的方法,但仍然使用单个 Btree 查找?
回答一些问题:
该数组缓存了一个复杂计算的结果——复杂到实时完成。在数十亿个可能的值中,只有数百万个产生有效结果。该数组看起来像 1234567 => 23457, 1234999 => 74361, ...。它被保存到一个几兆字节的 PHP 文件中,并在执行开始时 include_once-d。初始加载时间无关紧要。如果未找到该键,则仅表示此特定值不会返回有效结果。问题是每秒完成 50k+。
结论
由于无法通过单次查找和错误处理来获取值,因此我无法接受单个答案。相反,我赞成所有伟大的贡献。
最有价值的输入:
- 使用 array_key_exists,因为它比替代品更快
- 查看 PHP 的 QuickHash
关于 PHP 如何处理数组有很多困惑。如果你查看源代码,你会发现所有的数组都是平衡树。构建自己的查找方法在 C 和 C++ 中很常见,但在 PHP 等高级脚本语言中性能不佳。