SplFixedArray クラス
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
はじめに
SplFixedArray クラスは配列の主要な機能を提供します。 SplFixedArray と通常の PHP の配列との主な違いは、 SplFixedArray は手動でリサイズしなければならないことと、 整数値で指定した範囲内の添字しか使用できないところです。 これにより、標準の array よりメモリ消費が少なくて済みます。
クラス概要
/* メソッド */
}変更履歴
バージョン | 説明 |
---|---|
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
目次
- SplFixedArray::__construct — 新しい固定長配列を作成する
- SplFixedArray::count — 配列のサイズを返す
- SplFixedArray::current — 現在の配列の要素を返す
- SplFixedArray::fromArray — PHP の配列を SplFixedArray インスタンスにインポートする
- SplFixedArray::getIterator — 配列を走査するためのイテレータを取得する
- SplFixedArray::getSize — 配列のサイズを取得する
- SplFixedArray::jsonSerialize — JSON に変換可能な値の表現を返す
- SplFixedArray::key — 現在の配列の添字を返す
- SplFixedArray::next — 次のエントリに進む
- SplFixedArray::offsetExists — 指定した添字が存在するかどうかを返す
- SplFixedArray::offsetGet — 指定した添字の値を返す
- SplFixedArray::offsetSet — 指定した添字の新しい値を設定する
- SplFixedArray::offsetUnset — 指定した添字の値を消去する
- SplFixedArray::rewind — イテレータを先頭に巻き戻す
- SplFixedArray::__serialize — SplFixedArray オブジェクトをシリアライズする
- SplFixedArray::setSize — 配列のサイズを変更する
- SplFixedArray::toArray — 固定長配列から PHP の配列を返す
- SplFixedArray::__unserialize — data パラメータを SplFixedArray オブジェクトに復元する
- SplFixedArray::valid — 配列にまだ要素があるかどうかを調べる
- SplFixedArray::__wakeup — アンシリアライズ後に配列を再初期化する
+add a note
User Contributed Notes 6 notes
artaxerxes ¶
12 years ago
As the documentation says, SplFixedArray is meant to be *faster* than array. Do not blindly believe other people's benchmarks, and beextra careful with the user comments on php.net. For instance, nairbv's benchmark code is completely wrong. Among other errors, it intends to increase the size of the arrays, but always initialize a 20 elements SplFixedArray.
On a PHP 5.4 64 bits linux server, I found SplFixedArray to be always faster than array().
* small data (1,000):
* write: SplFixedArray is 15 % faster
* read: SplFixedArray is 5 % faster
* larger data (512,000):
* write: SplFixedArray is 33 % faster
* read: SplFixedArray is 10 % faster
herhor67 at interia dot pl ¶
4 years ago
Memory usage for arrays of 1132766 ints (data derived from some 1kx1k img):
Regular: 76453160B (67.5B/int)
SplFixed: 18898744B (16.7B/int)
In my application, SFA uses 75% less RAM, which is a life-saver.
Speed comparison:
Regular: 449ms
SplFixed (resized before every element): 791ms
SplFixed (fully preallocated): 392ms
SplFixed (preall-d to 1M and then resized): 547ms
Pros and cons:
+ much more efficient RAM-wise
+ a bit faster if max size is known
~ a bit slower if max size is only approximated
- much slower if max size is not known
- cannot be used with most array functions
To sum up:
SplFixedArray is a very good choice for storing giant amount of data, though only as long as you at least roughly know the size and can work without array functions.
chrisstocktonaz at gmail dot com ¶
15 years ago
Note, that this is considerably faster and should be used when the size of the array is known. Here are some very basic bench marks:
<?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;
}
?>
OUTPUT
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 ¶
14 years ago
Memory footprint of splFixedArray is about 37% of a regular "array" of the same size.
I was hoping for more, but that's also significant, and that's where you should expect to see difference, not in "performance".
CK ¶
1 year ago
Be warned that SplFixedArray does not provide all of the main functionalities of array. For example, it does not support array_slice. SplFixedArray should be far more efficient at supporting such array operations than normal arrays (since it should be simply a contiguous slice). Check that all your main array functions are really supported before trying to use SplFixedArray instead of array. With JIT in PHP8, some loops to polyfill these are perhaps now realistic, but still not as fast as native functions.