当使用in_array()函数来查找一个值是否在一个数组中存在时,如果该数组中的元素数量较多,该函数的性能会受到影响。本攻略将详细讲解如何遭遇php的in_array()低性能问题以及优化的方法,包含以下几个方面:
当使用in_array()
函数来查找一个值是否在一个数组中存在时,如果该数组中的元素数量较多,该函数的性能会受到影响。本攻略将详细讲解如何遭遇php的in_array()
低性能问题以及优化的方法,包含以下几个方面:
- 性能分析
- 优化方案
性能分析
查看API文档
在使用in_array()
函数之前,我们需要先了解这个函数的使用方式和限制条件。可以查看官方文档或者使用get_defined_functions()
来获取到PHP中的所有函数列表。
使用phpbench工具
phpbench是一个用于基准测试和性能分析的工具,它可以帮助我们更加准确地分析出代码的性能问题。
下面是一个使用phpbench来测试in_array()
函数性能的示例:
<?php
require_once 'vendor/autoload.php';
$array = range(1,100000);
echo 'in_array() test case:' . "\n";
$phpbench = new \PhpBench\Benchmark\Metadata\Annotations\PhpBench();
$phpbench->setIterations(10);
$phpbench->setWarmup(3);
$phpbench->setMax(5);
$phpbench->setRevs(50);
$phpbench->setOutputTimeUnit('milliseconds', 0);
$phpbench->setOutputMode('aggregate');
$phpbench->setOutput('table');
class InArrayTest
{
/**
* @Subject
*/
public function benchInArray()
{
in_array(50000, $array);
}
}
运行phpbench,可以得到类似下面的测试结果:
+------------------+----------------+----------------+----------------+----------------+
| benchmark | subject | revs | mem | time |
+------------------+----------------+----------------+----------------+----------------+
| InArrayBench\InA | benchInArray | 50 | 65,864.00b | 0.02±0.00ms |
| rrayTest | | | | |
+------------------+----------------+----------------+----------------+----------------+
2 subjects encountered, 2 subjects successful, 0 assertions passed, 0 skipped, 0 errors, 0 failures
从测试结果来看,in_array
函数相对于第一种快速查找方式,其性能较低,所以需要考虑优化方案。
优化方案
使用isset或者array_key_exists
相对于in_array()
函数,isset
与array_key_exists()
函数在判断一个值是否在数组中存在时有较高的性能,并且比较不容易出现低性能问题。
以下是使用array_key_exists()
的示例:
<?php
$array = range(1,100000);
echo 'array_key_exists() test case:' . "\n";
$phpbench = new \PhpBench\Benchmark\Metadata\Annotations\PhpBench();
$phpbench->setIterations(10);
$phpbench->setWarmup(3);
$phpbench->setMax(5);
$phpbench->setRevs(50);
$phpbench->setOutputTimeUnit('milliseconds', 0);
$phpbench->setOutputMode('aggregate');
$phpbench->setOutput('table');
class ArrayKeyExistsTest
{
/**
* @Subject
*/
public function benchArrayKeyExists()
{
array_key_exists(50000, $array);
}
}
运行phpbench,可以得到类似下面的测试结果:
+------------------+-----------------+----------------+----------------+----------------+
| benchmark | subject | revs | mem | time |
+------------------+-----------------+----------------+----------------+----------------+
| ArrayKeyExistsBe | benchArrayKeyEx | 50 | 65,864.00b | 0.00±0.00ms |
| nch\ArrayKeyExis | ists | | | |
| Test | | | | |
+------------------+-----------------+----------------+----------------+----------------+
2 subjects encountered, 2 subjects successful, 0 assertions passed, 0 skipped, 0 errors, 0 failures
使用哈希表
相对于数组来说,哈希表是一种更为快速的数据结构,使用哈希表来存储需要查询的元素,可以在查询时获得更好的性能,以下是使用哈希表的示例:
<?php
$array = array_flip(range(1, 100000));
echo 'hash table test case:' . "\n";
$phpbench = new \PhpBench\Benchmark\Metadata\Annotations\PhpBench();
$phpbench->setIterations(10);
$phpbench->setWarmup(3);
$phpbench->setMax(5);
$phpbench->setRevs(50);
$phpbench->setOutputTimeUnit('milliseconds', 0);
$phpbench->setOutputMode('aggregate');
$phpbench->setOutput('table');
class HashTableTest
{
/**
* @Subject
*/
public function benchHashTable()
{
isset($array[50000]);
}
}
运行phpbench,可以得到类似下面的测试结果:
+------------------+----------------+----------------+----------------+----------------+
| benchmark | subject | revs | mem | time |
+------------------+----------------+----------------+----------------+----------------+
| HashTableBench\H | benchHashTable | 50 | 65,864.00b | 0.00±0.00ms |
| ashTableTest | | | | |
+------------------+----------------+----------------+----------------+----------------+
2 subjects encountered, 2 subjects successful, 0 assertions passed, 0 skipped, 0 errors, 0 failures
使用SplFixedArray
如果数组的元素数量确定且较大,使用SplFixedArray
可以获得更好的性能提升。
以下是使用SplFixedArray
的示例:
<?php
$array = new SplFixedArray(100000);
for ($i = 0; $i < 100000; $i++) {
$array[$i] = $i+1;
}
echo 'spl fixed array test case:' . "\n";
$phpbench = new \PhpBench\Benchmark\Metadata\Annotations\PhpBench();
$phpbench->setIterations(10);
$phpbench->setWarmup(3);
$phpbench->setMax(5);
$phpbench->setRevs(50);
$phpbench->setOutputTimeUnit('milliseconds', 0);
$phpbench->setOutputMode('aggregate');
$phpbench->setOutput('table');
class SplFixedArrayTest
{
/**
* @Subject
*/
public function benchSplFixedArray()
{
isset($array[50000]);
}
}
运行phpbench,可以得到类似下面的测试结果:
+------------------+------------------+----------------+----------------+----------------+
| benchmark | subject | revs | mem | time |
+------------------+------------------+----------------+----------------+----------------+
| SplFixedArrayBen | benchSplFixedArr | 50 | 65,864.00b | 0.00±0.00ms |
| ch\SplFixedArray | ayTest | | | |
+------------------+------------------+----------------+----------------+----------------+
2 subjects encountered, 2 subjects successful, 0 assertions passed, 0 skipped, 0 errors, 0 failures
综上所述,我们可以通过上述方案来优化in_array()
函数的性能问题。
本文标题为:遭遇php的in_array低性能问题
基础教程推荐
- PHP XML Expat解析器知识点总结 2022-12-20
- thinkphp5.1的model模型自动更新update_time字段实例讲解 2023-05-20
- Tp5 实现管理Ueditor 百度编辑器上传的图片 2023-08-30
- PHP文件操作实例总结【文件上传、下载、分页】 2022-11-28
- PHP8.0新功能之Match表达式的使用 2023-04-25
- php中&&和||逻辑运算符的高级简写(缩写条件)用法由浅入深讲解 原创 2023-07-04
- PHP实现顺时针打印矩阵(螺旋矩阵)的方法示例 2022-10-05
- PHP+jQuery实现即点即改功能示例 2022-12-29
- PHP 7.1中利用OpenSSL代替Mcrypt加解密的方法详解 2022-10-02
- 详解PHP队列的实现 2022-12-30