SplFixedArray 类

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

简介

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

类概要

class SplFixedArray implements IteratorAggregate, ArrayAccess, Countable, JsonSerializable {
/* 方法 */
public __construct(int $size = 0)
public count(): int
public current(): mixed
public static fromArray(array $array, bool $preserveKeys = true): SplFixedArray
public getSize(): int
public key(): int
public next(): void
public offsetExists(int $index): bool
public offsetGet(int $index): mixed
public offsetSet(int $index, mixed $value): void
public offsetUnset(int $index): void
public rewind(): void
public __serialize(): array
public setSize(int $size): bool
public toArray(): array
public __unserialize(array $data): void
public valid(): bool
public __wakeup(): void
}

变更日志

版本 描述
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: Index invalid or out of range
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

目录

添加注释

用户贡献注释 8 notes

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

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

在我的应用程序中,SFA 使用了 75% 的 RAM,这真是一个救命稻草。

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

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

总结
SplFixedArray 是存储大量数据的绝佳选择,但前提是你至少大体上知道大小并且可以在没有数组函数的情况下工作。
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;
}
?>

输出
Testing size: 1000
Array(): 0.00046396255493164
SplArray(): 0.00023293495178223

Testing size: 2000
Array(): 0.00057101249694824
SplArray(): 0.0003058910369873

Testing size: 4000
Array(): 0.0015869140625
SplArray(): 0.00086307525634766

Testing size: 8000
Array(): 0.0024251937866211
SplArray(): 0.00211501121521

Testing size: 16000
Array(): 0.0057680606842041
SplArray(): 0.0041120052337646

Testing size: 32000
Array(): 0.011334896087646
SplArray(): 0.007631778717041

Testing size: 64000
Array(): 0.021990060806274
SplArray(): 0.013560056686401

Testing size: 128000
Array(): 0.053267002105713
SplArray(): 0.030976057052612

Testing size: 256000
Array(): 0.10280108451843
SplArray(): 0.056283950805664

Testing size: 512000
Array(): 0.20657992362976
SplArray(): 0.11510300636292

Testing size: 1024000
Array(): 0.4138810634613
SplArray(): 0.21826505661011

Testing size: 2048000
Array(): 0.85640096664429
SplArray(): 0.46247816085815

Testing size: 4096000
Array(): 1.7242450714111
SplArray(): 0.95304894447327

Testing size: 8192000
Array(): 3.448086977005
SplArray(): 1.96746301651
alex dot andrienko at gmail dot com
13 年前
splFixedArray 的内存占用约为相同大小的常规“数组”的 37%。
我原本希望更高,但这也很显著,这就是你应该期望看到差异的地方,而不是在“性能”方面。
Anonymous
6 年前
getSize() 和 count() 返回相同的值
CK
1 年前
请注意,SplFixedArray 并不提供数组的所有主要功能。例如,它不支持 array_slice。SplFixedArray 应该比普通数组更有效地支持这些数组操作(因为它应该只是一个连续的切片)。在尝试使用 SplFixedArray 代替数组之前,请确保所有主要数组函数都得到支持。使用 PHP8 中的 JIT,一些用于填充这些函数的循环现在可能比较现实,但仍然不如本机函数快。
Anonymous
6 年前
PHP 数组非常快,尤其是在 PHP7 中,速度更快。你几乎不需要使用它。在某些情况下,使用它比使用数组更好,但要注意它们并不明显。
php at stij dot nospam dot npeete dot nospam dot rs dot nl
6 年前
请注意,(截至 PHP 7.1)SplFixedArray 每个数组项使用 16 字节(!) 。这可以通过以下方式轻松检查

<?php
ini_set
('memory_limit', '4M');
$array = new SplFixedArray(1000000);
//PHP 致命错误:允许的内存大小为 4194304 字节耗尽(尝试分配 16000000 字节)
?>

因此,如果你正在考虑使用 SplFixedArray 因为你需要使用包含大量项目的巨大数组,请确保你有足够的内存来支持它们。
To Top