PHP SplFixedArray出现错误或性能低下?
所以我制作了这个简单的脚本来测试PHP SplFixedArray出现错误或性能低下?,php,performance,Php,Performance,所以我制作了这个简单的脚本来测试SplFixedArray对象,看看它的性能有多好 传统的阵列法 ini_set('memory_limit', '2048M'); $start = microtime(true); $memStart = memory_get_peak_usage(true); $loop = 1000000; $array = []; for ($i = 0; $i < $loop; ++$i) { $arr = ['a'];
SplFixedArray
对象,看看它的性能有多好
传统的阵列法
ini_set('memory_limit', '2048M');
$start = microtime(true);
$memStart = memory_get_peak_usage(true);
$loop = 1000000;
$array = [];
for ($i = 0; $i < $loop; ++$i) {
$arr = ['a'];
$array[$i] = $arr;
}
$end = microtime(true);
$memEnd = memory_get_peak_usage(true);
echo 'Time: ' . ($end - $start) . "\n";
echo 'Mem: ' . ($memEnd - $memStart) / 1024 / 1024 . 'Mb';
//Display: Time: 0.037514925003052 Mem: 28Mb
从文档中看,
SplFixedArray
是否承诺具有更好的性能和内存?为什么会这样呢。那么我们到底应该在什么情况下使用它呢?SplFixedArray是一种特殊类型的对象,通常表现为数组,但有以下限制:
SplFixedArray
具有固定大小SplFixedArray
的方法在数组上的实现速度更快
至于您的示例-请注意,在第二个示例中,您创建了100000个新的SplFixedArray
对象(与第一个示例不同,在第一个示例中,您只创建了一个数组)
以您的示例为例,当在循环中删除新SplFixedArray
的创建时,只需为数组的每个元素设置值a
,我得到的结果如下:
$start = microtime(true);
$memStart = memory_get_peak_usage(true);
$loop = 100000;
$array = new SplFixedArray($loop);
for ($i = 0; $i<$loop; $i++) {
$array[$i] = 'a';
}
$end = microtime(true);
$memEnd = memory_get_peak_usage(true);
echo "Time: " . ($end - $start) . "\n";
echo "Mem: " . ($memEnd - $memStart)/1024/1024 . 'Mb';
// Time: 0.0023539066314697 Mem: 2Mb
$start=microtime(真);
$memStart=内存获取峰值使用率(true);
$loop=100000;
$array=新的SplFixedArray($loop);
对于($i=0;$i而言,SplFixedArray
是一种特殊类型的对象,通常表现为数组,但有以下限制:
与常规数组不同,SplFixedArray
具有固定大小
与常规数组不同,SplFixedArray的键只能是整数
由于这两个特性,SplFixedArray
的方法在数组上的实现速度更快
至于您的示例-请注意,在第二个示例中,您创建了100000个新的SplFixedArray
对象(与第一个示例不同,在第一个示例中,您只创建了一个数组)
以您的示例为例,当在循环中删除新SplFixedArray
的创建时,只需为数组的每个元素设置值a
,我得到的结果如下:
$start = microtime(true);
$memStart = memory_get_peak_usage(true);
$loop = 100000;
$array = new SplFixedArray($loop);
for ($i = 0; $i<$loop; $i++) {
$array[$i] = 'a';
}
$end = microtime(true);
$memEnd = memory_get_peak_usage(true);
echo "Time: " . ($end - $start) . "\n";
echo "Mem: " . ($memEnd - $memStart)/1024/1024 . 'Mb';
// Time: 0.0023539066314697 Mem: 2Mb
$start=microtime(真);
$memStart=内存获取峰值使用率(true);
$loop=100000;
$array=新的SplFixedArray($loop);
对于($i=0;$iSplFixedArray
对于它所设计的特定用例来说效率更高。如果它速度更快,占用的内存更少,那么它将作为所有数组的默认实现,实际上PHP7会根据您使用每个数组的方式自动选择多个实现
使用固定长度数组的想法是,通过预先设置长度,引擎不需要猜测要分配多少内存,也不需要在使数组变长或变短时重新安排内存。因此,为了比较它们,我们需要使用一个基准测试,这将产生不同,例如从空数组开始并添加一个毫秒关于它的要素:
$loop = 1000000;
$array = [];
for ($i = 0; $i < $loop; ++$i) {
$array[] = 42;
}
这在我的PHP7.2机器上运行需要1.5秒或更长时间,而如果我编写$array=[]
,则需要0.2秒。显然,创建新的SplFixedArray
实例需要付出代价,在选择是否使用它们时需要考虑到这一点
对于“多维数组”,这可能是一个重要因素,因为无法预先分配多个维度,您必须为外部数组中的每个项创建新实例。可以实现不同的结构来优化这种情况,但从7.4版开始,PHP中没有内置任何结构。SplFixedArray
对于它是为特定的用例而设计的。如果它速度更快,占用的内存更少,那么它将作为所有数组的默认实现,实际上PHP7会根据您使用每个数组的方式自动选择多个实现
使用固定长度数组的想法是,通过预先设置长度,引擎不需要猜测要分配多少内存,也不需要在使数组变长或变短时重新安排内存。因此,为了比较它们,我们需要使用一个基准测试,这将产生不同,例如从空数组开始并添加一个毫秒关于它的要素:
$loop = 1000000;
$array = [];
for ($i = 0; $i < $loop; ++$i) {
$array[] = 42;
}
这在我的PHP7.2机器上运行需要1.5秒或更长时间,而如果我编写$array=[]
,则需要0.2秒。显然,创建新的SplFixedArray
实例需要付出代价,在选择是否使用它们时需要考虑到这一点
对于“多维数组”,这可能是一个重要因素,因为无法预先分配多个维度,您必须为外部数组中的每个项创建新实例。可以实现不同的结构来优化这种情况,但从7.4版开始,PHP中没有内置任何结构。像这样的微优化往往是一个愚蠢的问题ole下降。超过10万次迭代的百分之三百秒?我不会担心的。@ceejayoz我用一百万更新了这个问题。这是不是微优化取决于你如何看待它。我不希望脚本在我不能用一些代码行将其优化为100 MB时消耗1Gb内存。你仍然会创建多个splFixedArray
对象,而不仅仅是一个。请再次阅读我的文章并给出解释。像这样的微优化往往是一个愚蠢的兔子洞。超过10万次迭代的百分之三百秒?我不会担心的。@ceejayoz我用100万更新了这个问题。这是不是微优化取决于你如何使用它当我不能用一些代码行优化脚本使其达到100Mb时,我不想让脚本消耗1Gb内存。你仍然可以创建多个splfixedaray
对象,而不仅仅是一个。请重新阅读我的文章并给出解释。我将'a'
更改为['a']
甚至$arr=['a'];$arra
$loop = 1000000;
for ($i = 0; $i < $loop; ++$i) {
$array = new SplFixedArray(1);
}