PHP Conference Japan 2024

SplFixedArray 類別

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

簡介

SplFixedArray 類別提供了陣列的主要功能。SplFixedArray 與一般 PHP 陣列的主要區別在於 SplFixedArray 必須手動調整大小,並且只允許範圍內的整數作為索引。優點是它比標準 陣列 使用更少的記憶體。

類別概要

類別 SplFixedArray 實作 IteratorAggregate, ArrayAccess, Countable, JsonSerializable {
/* 方法 */
公開 __construct(整數 $size = 0)
公開 count(): 整數
公開 current(): 混合
公開 靜態 fromArray(陣列 $array, 布林 $preserveKeys = true): SplFixedArray
公開 getSize(): 整數
公開 key(): 整數
公開 next():
公開 offsetExists(整數 $index): 布林
公開 offsetGet(整數 $index): 混合
公開 offsetSet(整數 $index, 混合 $value):
公開 offsetUnset(整數 $index):
公開 rewind():
公開 setSize(int $size): true
公開 toArray(): 陣列
公開 __unserialize(陣列 $data): void
公開 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 則註記

artaxerxes
12 年前
如同文件中所述,SplFixedArray 的設計比 array *更快*。不要盲目相信其他人的基準測試,並且要格外小心 php.net 上的使用者評論。例如,nairbv 的基準測試程式碼完全錯誤。除了其他錯誤之外,它還打算增加陣列的大小,但總是初始化一個包含 20 個元素的 SplFixedArray。

在 64 位元 Linux 伺服器上的 PHP 5.4 中,我發現 SplFixedArray 總是比 array() 快。
* 小型資料 (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 使用的 RAM 減少了 75%,這是一個救星。

速度比較
一般陣列:449 毫秒
SplFixed(在每個元素之前調整大小):791 毫秒
SplFixed(完全預先分配):392 毫秒
SplFixed(預先分配到 1M,然後調整大小):547 毫秒

優缺點
+ RAM 使用效率更高
+ 如果知道最大大小,速度會稍快
~ 如果只知道大概的最大大小,速度會稍慢
- 如果不知道最大大小,速度會慢很多
- 無法與大多數陣列函式一起使用

總結
SplFixedArray 是一個非常好的選擇,用於儲存大量資料,但前提是您至少大致瞭解大小並且可以在沒有陣列函式的情況下工作。
chrisstocktonaz at gmail dot com
15 年前
請注意,這 considerably 快,並且應該在已知陣列大小的情況下使用。以下是一些非常基本的基準測試

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

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

輸出結果
測試大小: 1000
陣列(): 0.00046396255493164
Spl陣列(): 0.00023293495178223

測試大小: 2000
陣列(): 0.00057101249694824
Spl陣列(): 0.0003058910369873

測試大小: 4000
陣列(): 0.0015869140625
Spl陣列(): 0.00086307525634766

測試大小: 8000
陣列(): 0.0024251937866211
Spl陣列(): 0.00211501121521

測試大小: 16000
陣列(): 0.0057680606842041
Spl陣列(): 0.0041120052337646

測試大小: 32000
陣列(): 0.011334896087646
Spl陣列(): 0.007631778717041

測試大小: 64000
陣列(): 0.021990060806274
Spl陣列(): 0.013560056686401

測試大小: 128000
陣列(): 0.053267002105713
Spl陣列(): 0.030976057052612

測試大小: 256000
陣列(): 0.10280108451843
Spl陣列(): 0.056283950805664

測試大小: 512000
陣列(): 0.20657992362976
Spl陣列(): 0.11510300636292

測試大小: 1024000
陣列(): 0.4138810634613
Spl陣列(): 0.21826505661011

測試大小: 2048000
陣列(): 0.85640096664429
Spl陣列(): 0.46247816085815

測試大小: 4096000
陣列(): 1.7242450714111
Spl陣列(): 0.95304894447327

測試大小: 8192000
陣列(): 3.448086977005
Spl陣列(): 1.96746301651
alex dot andrienko at gmail dot com
14 年前
splFixedArray 的記憶體佔用量大約是相同大小的普通「陣列」的 37%。
我希望更多,但這也很重要,這就是您應該期望看到差異的地方,而不是在「效能」方面。
匿名
6 年前
getSize() 和 count() 返回相同的值
CK
1 年前
請注意,SplFixedArray 並不提供所有主要的陣列功能。例如,它不支援 array_slice。SplFixedArray 在支援此類陣列操作方面應該比普通陣列效率高得多(因為它應該只是一個連續的片段)。在嘗試使用 SplFixedArray 取代陣列之前,請檢查所有主要的陣列函式是否真的受到支援。由於 PHP8 中的 JIT,一些用於填充這些功能的迴圈現在或許可行,但仍然不如原生函式快速。
To Top