jgmdev/lessram

使用更少内存的纯PHP实现数组数据结构。

dev-master 2019-07-18 06:04 UTC

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目录和基准测试。

待办事项

添加关联数据结构,也称为映射,其中索引可以是任何字符串。