PHP扩展之数组字符串处理

时间:2017-05-31作者:klpeng分类:PHP浏览:2270评论:1

今天介绍一下PHP扩展来处理数组和字符串,附带一个对比原生PHP的处理效率:

我的测试机是装的PHP5.6.12,实现下面这个功能:

function phprandstr($a, $z, $n) {
    $b = array();
    $max = count($a);
    for ($i = 0; $i < $n; $i++) {
        $tmp = "";
        for ($j = 0; $j < $z; $j++) {
            $zix = mt_rand(0, ($max - 1));
            $tmp.=$a[$zix];
        }
        array_push($b, $tmp);
    }
    return $b;
}

很简单对不对,对一个数组里面的字符,随机取出来拼接,然后push到一个新的数组,下面来看PHP扩展的实现:

继续在我之前那个ligphp扩展里面写,编辑php_ligphp.h,添加一个randStr()函数:

PHP_FUNCTION(randStr);

然后我们来重点看一下ligphp.c里面的代码:

PHP_FUNCTION(randStr) {
    zval *arr, **data;
    long z;
    long n;
    int i, j, zix;
    char *s = NULL, *str;
    HashTable * arr_hb;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "all", &arr, &z, &n) == FAILURE) {
        RETURN_NULL();
    }
    arr_hb = Z_ARRVAL_P(arr);

    long length = zend_hash_num_elements(arr_hb);
    if (z > length) {
        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "参数二不能超过数组长度");
        RETURN_NULL();
    }
    array_init_size(return_value, n);
    for (i = 0;i < n;i++) {
        str = (char *)malloc(z + 1);
        memset(str, '\0', z + 1);
        for(j = 0;j < z;j++) {
            zix = php_rand() % length;
            if(zend_hash_index_find(arr_hb, zix, (void **)&data)== FAILURE) {
                return;
            }
            s = Z_STRVAL_PP(data);
            strncat(str, s, strlen(s));
        }
        add_index_string(return_value, i, str, 1);
    }
    return;
};

解释下上面的代码;

1.我们首先用zend_parse_parameters()函数接收参数,可以看到,接收一个数组类型的zval结构arr,2个long整型z和n;

2.用Z_ARRVAL_P宏,取出arr的值赋给哈希表结构类型的arr_hb,用zend_hash_num_elements()函数获取hashtable的长度便于下面的验证和算法处理;

3.用array_init_size()函数初始化return_value为一个数组;

4.开始循环处理,这里代码比较简单,用到的2个C函数malloc()动态分配内存空间和memset()把str的内存地址中没一个字节都设置成'\0'空字符串,即NULL;

5.zend_hash_index_find()函数是用于数字型索引数组的查找,strncat()是C函数用于拼接字符串的,add_index_string()函数类似PHP的array_push(),只不过是要指定index的。


把randStr注册到函数表中然后编译,接下来,我们来做一个简单测试,从26个英文字母里面随机取50000个10位的字符串,对比PHP执行和PHP扩展执行的效率:

$a = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
$t1 = microtime(true);
//$b=phprandstr($a,10,50000);
$b = randStr($a, 10, 50000);
$t2 = microtime(true);
echo "耗时:" . ($t2 - $t1) . "\n";

在我的机器上实测PHP处理需要0.162毫秒,PHP扩展处理0.032毫秒,相差大概五倍,可能毫秒级的你不在乎,但是想想,一次请求让你等1秒,你可以接受,让你等五秒,你估计炸毛了。。。

打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

  • 评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢