gpt4 book ai didi

php - 如何从 PHP 扩展返回数组,而不将其复制到内存中?

转载 作者:可可西里 更新时间:2023-11-01 12:36:23 24 4
gpt4 key购买 nike

我正在开发一个 PHP 扩展,其中一个对象方法需要返回一个数组 zval

方法如下:

ZEND_METHOD(myObject, myMethod)
{
zval **myArrayProperty;
if (zend_hash_find(Z_OBJPROP_P(getThis()), "myArrayProperty", sizeof("myArrayProperty"), (void **) &myArrayProperty) == FAILURE) {
RETURN_FALSE;
}
RETURN_ZVAL(*myArrayProperty, 1, 0);
}

代码工作正常并完成预期的事情 - 它返回对象的 myArrayProperty。但是,我想优化流程。

myArrayProperty 存储一个数组,它可以很大。 RETURN_ZVAL() 宏复制该数组以返回值。复制过程需要大量时间来获取内存并复制所有数组值。同时,返回的数组通常用于只读操作。因此,一个很好的优化是使用 PHP 的引用计数机制,并且不要复制 myArrayProperty 内容。相反,我会增加 myArrayPropertyrefcount 并返回指向它的指针。这与在 PHP 扩展中处理变量时通常使用的策略相同。

但是,似乎没有办法做到这一点——您必须复制值才能从 PHP 扩展函数返回它。通过引用将函数签名更改为返回值不是一个选项,因为它链接了属性和返回值——即稍后更改返回值,也会更改属性。这是 Not Acceptable 行为。

无法进行引用计数看起来很奇怪,因为 PHP 中的代码相同:

function myMethod() {
{
return $this->myArrayProperty;
}

是通过引用计数机制优化的。这就是为什么我在 StackOverflow 上问这个问题,以防我遗漏了什么。

那么,有没有一种方法可以从 PHP 扩展中的函数返回数组,而无需在内存中复制数组?

最佳答案

如果您的函数按值返回,这只能从 PHP 5.6(当前主版本)开始使用 RETURN_ZVAL_FAST 宏:

RETURN_ZVAL_FAST(*myArrayProperty);

如果您的函数返回引用(arginfo 中的 return_reference=1),您可以使用以下代码返回:

zval_ptr_dtor(&return_value);
SEPARATE_ZVAL_TO_MAKE_IS_REF(myArrayProperty);
Z_ADDREF_PP(myArrayProperty);
*return_value_ptr = *myArrayProperty;

如果您的函数按值返回并且您使用的是 PHP 5.5 或更早版本,您仍然可以优化 refcount=1 情况:

if (Z_REFCOUNT_PP(myArrayProperty) == 1) {
RETVAL_ZVAL(*myArrayProperty, 0, 1);
Z_ADDREF_P(return_value);
*myArrayProperty = return_value;
} else {
RETVAL_ZVAL(*myArrayProperty, 1, 0);
}

关于php - 如何从 PHP 扩展返回数组,而不将其复制到内存中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17844379/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com