The SplFixedArray class provides the main functionalities of array. The main differences between a SplFixedArray and a normal PHP array is that the SplFixedArray is of fixed length and allows only integers within the range as indexes. The advantage is that it allows a faster array implementation.
Beispiel #1 SplFixedArray usage example
<?php
// Initialize the array with a fixed length
$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"
// Increase the size of the array to 10
$array->setSize(10);
$array[9] = "asdf";
// Shrink the array to a size of 2
$array->setSize(2);
// The following lines throw a 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";
}
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
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
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".
NOTE: This only affects CREATION time, NOT access time.
It does NOT create a true indexed array (which is what I was hoping for) but is still associative like all PHP arrays. The class requires a numeric key because it builds the array with a set number of items but still operates under the hood associatively. (or this is my assumption, as I performed benchmarks comparing 100,000 reads on a standard array and an SplFixedArray: Results were the same, while a true indexed array SHOULD in theory be faster than an associative)
The only performance gain is that you are not building the array piece by piece; Rather, the entire array is built at once and you can then fill it's values by numeric indexes... Therefor it is only reducing the creation overhead.
This is only useful in a situation when you know the size your array will be, for example filling it with items from a database query.
Though, object creation overhead means this method is slower for small arrays.
for example, if the other posters benchmark script is changed to a more realistic:
<?php
$elements = 20;
for($size = 1000; $size < 50000000; $size *= 2) {
echo PHP_EOL . "Testing size: $size" . PHP_EOL;
for($s = microtime(true), $i = 0; $i < $size; $i++) {
for($j=0,$container=array();$j < $elements; $j++ ) {
$container[$i] = NULL;
}
}
echo "Array(): " . (microtime(true) - $s) . PHP_EOL;
for($s = microtime(true), $i = 0; $i < $size; $i++) {
for( $j=0,$container=new SplFixedArray($elements);$j<$elements;$j++) {
$container[$i] = NULL;
}
}
echo "SplArray(): " . (microtime(true) - $s) . PHP_EOL;
}
we get:
Testing size: 1000
Array(): 0.0030221939086914
SplArray(): 0.0041899681091309
Testing size: 2000
Array(): 0.0060598850250244
SplArray(): 0.0083701610565186
Testing size: 4000
Array(): 0.012003898620605
SplArray(): 0.016681909561157
Testing size: 8000
Array(): 0.024173021316528
SplArray(): 0.033347129821777
Testing size: 16000
Array(): 0.048118829727173
SplArray(): 0.066897869110107
Testing size: 32000
Array(): 0.096546173095703
SplArray(): 0.13370203971863
Testing size: 64000
Array(): 0.1932430267334
SplArray(): 0.26755595207214
Testing size: 128000
Array(): 0.38473010063171
SplArray(): 0.5374698638916
Testing size: 256000
Array(): 0.77228307723999
SplArray(): 1.0708079338074
Testing size: 512000
Array(): 1.5438990592957
SplArray(): 2.1406710147858
Testing size: 1024000
Array(): 3.0910761356354
SplArray(): 4.3108429908752
Testing size: 2048000
Array(): 6.1561989784241
SplArray(): 8.612802028656
......
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