• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

PHP-FFI-实现list

php 搞java代码 3年前 (2022-05-21) 60次浏览 已收录 0个评论

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

<code class="php"><?<a href="https://www.gaodaima.com/tag/php" title="查看更多关于php的文章" target="_blank">php</a>
// php 字符串转C <a href="https://www.gaodaima.com/tag/char" title="查看更多关于char的文章" target="_blank">char</a>指针
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 $<a href="https://www.gaodaima.com/tag/ffi" title="查看更多关于ffi的文章" target="_blank">ffi</a>;
    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指针耗时比拟久,扔须要优化。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:PHP-FFI-实现list
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址