本文通过PHP FFI个性初步实现了list链表

<?php// php 字符串转C char指针function stringToCharPtr(string $str){    $strChar = str_split($str);    $c = FFI::new('char[' . count($strChar) . ']', false);    foreach ($strChar as $i => $char) {        $c[$i] = $char;    }    return FFI::cast(FFI::type('char *'), $c);}class FFIHelper{    private static $ffi;    public static function create()    {        if (empty(self::$ffi)) {            self::$ffi = \FFI::load("./test.h");        }        return self::$ffi;    }}class StringArray{    private $char;    private $capacity;    private $length;    public function __construct(int $capacity = 0)    {        if ($capacity > 0) {            $this->create($capacity);        }    }    /**     * 创立list     */    public function create(int $capacity)    {        if (!is_numeric($capacity) || $capacity <= 0) {            throw new \Exception("list长度不能够为0");        }        $this->char                = \FFI::new ('char*[' . ($capacity) . ']', false, true);        $this->capacity = $capacity;    }    public function append($string)    {        $postion = $this->length;        if ($postion >= $this->capacity) {            $this->grow($this->capacity * 2);        }        $this->char[$postion] = stringToCharPtr($string . "\0");        $this->length++;    }    public function get($postion)    {        return $this->ArrayList->data;    }    public function delete($postion)    {        if ($postion < 0) {            throw new \Exception("删除地位不能够小于0");        }        if ($postion > $this->ArrayList->length) {            throw new \Exception("删除地位大于list长度");        }        }    public function length()    {        return $this->length;    }    /**     * 减少数组长度     */    public function grow($size)    {        if ($size < $this->capacity) {            throw new \Exception("无需减少list容量");        }        $oldData = $this->char;        $newData = \FFI::new ('char*[' . ($size) . ']', false, true);        \FFI::memcpy($newData, $this->char, \FFI::sizeof($oldData) * $this->length);        $this->char                = $newData;        $this->capacity = $size;        \FFI::free($oldData);    }    public function getList()    {        return $this->char;    }    public function __destruct()    {    }}$star_memory = memory_get_usage();$start       = microtime(true);$list = new StringArray(2000000);$i    = 0;$data = [];while (true) {     $list->append("hello 你好");    //$data[] = "aaas你好" . $i;    $i++;    if ($i > 1000000) {        break;    }}//var_dump(FFI::string($list->get(0)));$end_memory = memory_get_usage();$elapsed    = microtime(true) - $start;echo "That took $elapsed seconds.\n";var_dump((($end_memory - $star_memory) / 1024 / 1024) . "M");

因为PHP底层字符串做了解决,雷同字符串会只存一次,通过计数器的形式来示意援用的次数,而本文中实现的字符串并未进行认为解决。因此,每次都会从新创立新的字符串。

通过文中代码测试,发现即便为对字符串进行解决,内存占用状况也会至多优化3倍以上,当然目前美中不足的是,字符串转为char指针耗时比拟久,扔须要优化。