PHP Conference Japan 2024

SplFixedArray 类

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

简介

SplFixedArray 类提供了数组的主要功能。SplFixedArray 与普通 PHP 数组的主要区别在于 SplFixedArray 必须手动调整大小,并且仅允许在范围内使用整数作为索引。优点是它比标准的 数组 使用更少的内存。

类概要

SplFixedArray 实现 IteratorAggregateArrayAccessCountableJsonSerializable {
/* 方法 */
公共的 __construct(整数 $size = 0)
公共的 count(): 整数
公共的 current(): 混合
公共的 静态的 fromArray(数组 $array, 布尔 $preserveKeys = ): SplFixedArray
公共的 getIterator(): 迭代器
公共的 getSize(): 整数
公共的 jsonSerialize(): 数组
公共的 key(): 整数
公共的 next():
公共的 offsetExists(整数 $index): 布尔
公共的 offsetGet(整数 $index): 混合
公共的 offsetSet(整数 $index, 混合 $value):
公共的 offsetUnset(整数 $index):
公共的 rewind():
公共的 __serialize(): 数组
公共的 setSize(整数 $size):
公共的 toArray(): 数组
公共的 __unserialize(数组 $data):
公共的 valid(): 布尔
}

变更日志

版本 描述
8.2.0 已将 SplFixedArray::__serialize()SplFixedArray::__unserialize() 魔术方法添加到 SplFixedArray 中。
8.1.0 SplFixedArray 现在实现了 JsonSerializable
8.0.0 SplFixedArray 现在实现了 IteratorAggregate。以前,实现了 Iterator

示例

示例 #1 SplFixedArray 用法示例

<?php
// 使用固定长度初始化数组
$array = new SplFixedArray(5);

$array[1] = 2;
$array[4] = "foo";

var_dump($array[0]); // NULL
var_dump($array[1]); // int(2)

var_dump($array["4"]); // string(3) "foo"

// 将数组的大小增加到 10
$array->setSize(10);

$array[9] = "asdf";

// 将数组的大小缩减到 2
$array->setSize(2);

// 以下行将抛出 RuntimeException:索引无效或超出范围
try {
var_dump($array["non-numeric"]);
} catch(
RuntimeException $re) {
echo
"RuntimeException: ".$re->getMessage()."\n";
}

try {
var_dump($array[-1]);
} catch(
RuntimeException $re) {
echo
"RuntimeException: ".$re->getMessage()."\n";
}

try {
var_dump($array[5]);
} catch(
RuntimeException $re) {
echo
"RuntimeException: ".$re->getMessage()."\n";
}
?>

以上示例将输出

NULL
int(2)
string(3) "foo"
RuntimeException: Index invalid or out of range
RuntimeException: Index invalid or out of range
RuntimeException: Index invalid or out of range

目录

添加注释

用户贡献注释 6 条注释

52
artaxerxes
12 年前
如文档所述,SplFixedArray 旨在比数组 *更快*。不要盲目相信其他人的基准测试,并对 php.net 上的用户评论格外小心。例如,nairbv 的基准测试代码完全错误。在其他错误中,它打算增加数组的大小,但始终初始化一个 20 个元素的 SplFixedArray。

在 PHP 5.4 64 位 Linux 服务器上,我发现 SplFixedArray 始终比 array() 快。
* 小数据 (1,000)
* 写入:SplFixedArray 快 15%
* 读取:SplFixedArray 快 5%
* 较大的数据 (512,000)
* 写入:SplFixedArray 快 33%
* 读取:SplFixedArray 快 10%
8
herhor67 at interia dot pl
4 年前
包含 1132766 个整数的数组的内存使用情况(数据来自某些 1kx1k 图像)
常规:76453160B(67.5B/int)
SplFixed:18898744B(16.7B/int)

在我的应用程序中,SFA 使用的 RAM 少 75%,这真是救星。

速度比较
常规:449 毫秒
SplFixed(每个元素之前都调整大小):791 毫秒
SplFixed(完全预分配):392 毫秒
SplFixed(预分配到 1M 然后调整大小):547 毫秒

优点和缺点
+ 内存效率更高
+ 如果已知最大大小,则速度略快
~ 如果仅近似最大大小,则速度略慢
- 如果未知最大大小,则速度慢得多
- 不能与大多数数组函数一起使用

总结
SplFixedArray 是存储大量数据的非常好的选择,但前提是您至少大致了解大小,并且可以在没有数组函数的情况下工作。
21
chrisstocktonaz at gmail dot com
15 年前
请注意,这快得多,并且在已知数组大小时应该使用。以下是一些非常基本的基准测试

<?php
for($size = 1000; $size < 50000000; $size *= 2) {
echo
PHP_EOL . "Testing size: $size" . PHP_EOL;
for(
$s = microtime(true), $container = Array(), $i = 0; $i < $size; $i++) $container[$i] = NULL;
echo
"Array(): " . (microtime(true) - $s) . PHP_EOL;

for(
$s = microtime(true), $container = new SplFixedArray($size), $i = 0; $i < $size; $i++) $container[$i] = NULL;
echo
"SplArray(): " . (microtime(true) - $s) . PHP_EOL;
}
?>

输出
测试大小:1000
Array():0.00046396255493164
SplArray():0.00023293495178223

测试大小:2000
Array():0.00057101249694824
SplArray():0.0003058910369873

测试大小:4000
Array():0.0015869140625
SplArray():0.00086307525634766

测试大小:8000
Array():0.0024251937866211
SplArray():0.00211501121521

测试大小:16000
Array():0.0057680606842041
SplArray():0.0041120052337646

测试大小:32000
Array():0.011334896087646
SplArray():0.007631778717041

测试大小:64000
Array():0.021990060806274
SplArray():0.013560056686401

测试大小:128000
Array():0.053267002105713
SplArray():0.030976057052612

测试大小:256000
Array():0.10280108451843
SplArray():0.056283950805664

测试大小:512000
Array():0.20657992362976
SplArray():0.11510300636292

测试大小:1024000
Array():0.4138810634613
SplArray():0.21826505661011

测试大小:2048000
Array():0.85640096664429
SplArray():0.46247816085815

测试大小:4096000
Array():1.7242450714111
SplArray():0.95304894447327

测试大小:8192000
Array():3.448086977005
SplArray():1.96746301651
11
alex dot andrienko at gmail dot com
14 年前
splFixedArray 的内存占用约为相同大小的常规“数组”的 37%。
我希望能更多,但这也很重要,这就是您应该期望看到差异的地方,而不是在“性能”上。
4
匿名
6 年前
getSize() 和 count() 返回相同的值
1
CK
1 年前
请注意,SplFixedArray 并未提供数组的所有主要功能。例如,它不支持 array_slice。SplFixedArray 在支持此类数组操作方面应该比普通数组效率高得多(因为它应该只是一个连续的切片)。在尝试使用 SplFixedArray 代替数组之前,请检查您所有主要的数组函数是否都真正受支持。在 PHP8 中使用 JIT,一些用于填充这些函数的循环现在可能很现实,但仍然不如原生函数快。
To Top