jgmdev / lessram
使用更少内存的纯PHP实现数组数据结构。
dev-master
2019-07-18 06:04 UTC
Requires
- php: >=7.1
Requires (Dev)
- phpunit/phpunit: ^8.2
This package is auto-updated.
Last update: 2024-09-20 10:14:05 UTC
README
比原生PHP数组消耗更少内存的PHP数组数据结构实现。但性能较低。要获取更快的版本,请查看ext目录下的C实现。
使用方法
目前该项目只包括两种实现ArrayAccess、Countable、Serializable和Iterator的数组结构,这两种结构是:
- StaticArray - 可以动态增长,但其元素不能修改。
- DynamicArray - 可以动态增长,其元素可以被修改或删除。
它们都只支持数字键,将来可能添加支持字符串索引的实现。
StaticArray 示例
$list = new LessRam\StaticArray(); $list[] = "value1"; $list[] = "value2"; $list[] = ["index" => "somearray"]; foreach($list as $value) { echo $value; } $list->clear();
DynamicArray 示例
$list = new LessRam\DynamicArray(); $list[] = "value1"; $list[] = "value2"; $list[] = ["index" => "somearray"]; foreach($list as $value) { echo $value; } $list[0] = "newvalue"; unset($list[1]); // Remove value2 print_r($list[1]); // show array which now took place of value2 $list->clear();
如上所示,除了存储字符串,它们还可以存储数组甚至对象。当插入此类变量时,它们会被序列化,从而节省内存;在需要访问时会被反序列化。这可以节省大量内存,但会影响性能,因此您应权衡您的需求。有关性能的更多信息,请查看下面的基准测试。
基准测试
下面显示的第一个结果是向每个测试的数据结构中插入字符串1048577次,第一个测试没有使用gzip压缩,而第二个测试使用了SplFixedArray和PHP原生数组的gzip压缩。
$list[] = "hello world" . $i;
结果
=======================================================================
String store test:
=======================================================================
Measure | StaticArray | DynamicArray | SplFixedArray | Native
add 1048577 | 0.42s | 0.29s | 0.10s | 0.15s
get two items | 0.00s | 0.00s | 0.00s | 0.00s
loop all | 1.31s | 2.11s | 0.03s | 0.02s
serialize | 0.08s | 0.04s | 0.20s | 0.31s
unserialize | 0.05s | 0.03s | 0.34s | 0.15s
total time | 1.87s | 2.48s | 0.69s | 0.66s
memory usage | 29MB | 19MB | 129MB | 113MB
=======================================================================
String store test gzipped (StaticArray and DynamicArray not compressed):
=======================================================================
Measure | StaticArray | DynamicArray | SplFixedArray | Native
add 1048577 | 0.44s | 0.35s | 31.95s | 10.72s
get two items | 0.00s | 0.00s | 0.00s | 0.00s
loop all | 1.28s | 2.10s | 0.03s | 0.02s
serialize | 0.08s | 0.05s | 0.44s | 0.16s
unserialize | 0.05s | 0.03s | 0.28s | 0.15s
total time | 1.86s | 2.53s | 32.71s | 11.09s
memory usage | 29MB | 19MB | 129MB | 113MB
第二个测试将数组存储在数据结构中1048577次,如下所示:
$list[] = ["name" => "hello world" . $i];
结果
=======================================================================
Array store test:
=======================================================================
Measure | StaticArray | DynamicArray | SplFixedArray | Native
add 1048577 | 0.79s | 0.60s | 0.34s | 0.24s
get two items | 0.00s | 0.00s | 0.00s | 0.00s
loop all | 1.99s | 4.36s | 0.23s | 0.12s
serialize | 0.12s | 0.08s | 0.43s | 0.84s
unserialize | 0.08s | 0.06s | 1.24s | 0.67s
total time | 2.98s | 5.10s | 2.25s | 2.06s
memory usage | 42MB | 32MB | 505MB | 489MB
=======================================================================
Array store test gzipped (StaticArray and DynamicArray not compressed):
=======================================================================
Measure | StaticArray | DynamicArray | SplFixedArray | Native
add 1048577 | 0.76s | 0.66s | 70.51s | 13.86s
get two items | 0.00s | 0.00s | 0.00s | 0.00s
loop all | 1.96s | 4.36s | 0.03s | 0.03s
serialize | 0.11s | 0.08s | 0.60s | 0.74s
unserialize | 0.07s | 0.05s | 0.38s | 0.17s
total time | 2.91s | 5.15s | 71.53s | 14.85s
memory usage | 42MB | 32MB | 161MB | 145MB
可以说,在内存使用和性能之间取得最佳平衡的是StaticArray实现。要运行自己的基准测试,请执行以下命令:
cd lessram
php bench.php
测试
已经编写了一些测试来检查这些结构的可靠性,但可能还需要更多的测试。要运行测试,请执行以下php单元执行文件:
cd lessram
./vendor/bin/phpunit
PHP C扩展(工作进展中)
我开始实现与PHP实现的数据结构相同的算法,还有很多工作要做,但基础工作应该已经到位。更多信息请查看ext目录和基准测试。
待办事项
添加关联数据结构,也称为映射,其中索引可以是任何字符串。