用C写了一个PHP冒泡排序的扩展,主要是想看看C和PHP的差距。以下有源码和测试的结果(C代码写的并不那么好,凑合着看吧)。
冒泡排序C扩展函数源码:PHP_FUNCTION(reson_sort)
{
zval *arr, *itemValue, *prefix_entry;
zend_string *string_key;
zend_ulong num_key, arr_len;
long *sortArr;
int loop=0;
int _i,_j,_temp; //排序控制变量
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &arr) == FAILURE)
{
return;
}
arr_len = zend_hash_num_elements(Z_ARRVAL_P(arr));
if(arr_len == 0)
{
return;
}
sortArr = (long *)emalloc(arr_len * sizeof(long));
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(arr), num_key, string_key, itemValue)
{
if (Z_TYPE_P(itemValue) == IS_LONG)
{
sortArr[loop++] = Z_LVAL_P(itemValue);
continue;
}
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Array type error, Elements must be int!");
} ZEND_HASH_FOREACH_END();
//开始冒泡排序
for(_i=0; _i
{
for(_j=0; _i+_j
{
if(sortArr[_j] > sortArr[_j+1])
{
_temp = sortArr[_j];
sortArr[_j] = sortArr[_j+1];
sortArr[_j+1] = _temp;
}
}
}
//处理返回值
for(_i=0; _i
{
add_next_index_long(return_value, sortArr[_i]);
}
//释放内存
efree(sortArr);
}
对C扩展的冒泡排序和PHP原生的冒泡排序分别做了20、50、100个元素的数组循环执行10000次的耗时和相差情况。
脚本运行环境:
PHP 7.1.6
Centos 64位 1核 512MB 的虚拟机。
为了数据更准确,执行了2轮,结果如下图:
可以看出,C比PHP还是要快很多的。
附:PHP排序和C扩展排序源码如下<?php
/**
* 对比c和php排序耗时
*/
compare(10000, 20); //10000次
compare(10000, 50); //10000次
compare(10000, 100); //10000次
function compare($times, $arrLen)
{
$arr = create_arr($arrLen);
//php
$pStart = microtime(true);
for($i=0; $i
{
$res = php_sort($arr);
}
$pCost = microtime(true) - $pStart;
echo 'php cost('.$times.'|'.$arrLen.'):' . $pCost . PHP_EOL;
//c
$cStart = microtime(true);
for($i=0; $i<10000; $i++)
{
$res = reson_sort($arr);
}
$cCost = microtime(true) - $cStart;
echo 'c cost('.$times.'|'.$arrLen.'):' . $cCost . PHP_EOL;
echo 'php/c:'.$pCost/$cCost.PHP_EOL.PHP_EOL;
}
function php_sort($arr)
{
$arr_len = count($arr);
for($_i=0; $_i
{
for($_j=0; $_i+$_j
{
if($arr[$_j] > $arr[$_j+1])
{
$_temp = $arr[$_j];
$arr[$_j] = $arr[$_j+1];
$arr[$_j+1] = $_temp;
}
}
}
return $arr;
}
function create_arr($arrLen)
{
$arr = [];
for($i=0; $i
{
$arr[] = mt_rand(1,100);
}
return $arr;
}
?>