今天介绍一下PHP扩展来处理数组和字符串,附带一个对比原生PHP的处理效率:
我的测试机是装的PHP5.6.12,实现下面这个功能:function phprandstr($a, $z, $n) {
$b = array();
$max = count($a);
for ($i = 0; $i
$tmp = "";
for ($j = 0; $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
str = (char *)malloc(z + 1);
memset(str, '\0', z + 1);
for(j = 0;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秒,你可以接受,让你等五秒,你估计炸毛了。。。
打赏
微信扫一扫,打赏作者吧~