我有两个用户定义排序函数的实现:堆排序和快速排序。我一直在权衡各种排序方法的好处/缺点,并决定做一些基准测试。
为什么PHP的原生usort()
功能如此之快?
我知道Heap Sort是O(log,n)并且它有它的好处,我也理解为什么快速排序在这个实现中优于heapsort;但为什么usort()
占主导地位呢? 可能是因为usort是php(源代码)的一部分,它的内部工作是利用C源代码吗?
以下是我的结果和实现:HeapSort.php,QuickSort.php和入口点sort.php
输出
Heapsort: 11.894743
Quicksort: 5.641383
usort: 1.180634
---------------------------------------
Total Time: 18.716766
sort.php
<?php
/* Author Jacob Psimos */
define('SIZE', 200000);
include('HeapSort.php');
include('QuickSort.php');
$array = array();
$array2 = array();
$array3 = array();
for($i = 0; $i < SIZE; $i++){
array_push($array, array('value' => SIZE - $i));
array_push($array2, array('value' => SIZE - $i));
array_push($array3, array('value' => SIZE - $i));
}
$start1 = microtime(true);
array_heapsort($array, 'cmp', SIZE);
$end1 = microtime(true);
//unset($array);
$start2 = microtime(TRUE);
array_quicksort($array2, 0, SIZE - 1, 'cmp');
$end2 = microtime(TRUE);
//unset($array2);
$start3 = microtime(TRUE);
usort($array3, 'cmp');
$end3 = microtime(TRUE);
//unset($array3);
printf("Heapsort: %f\n", $end1 - $start1);
printf("Quicksort: %f\n", $end2 - $start2);
printf("usort: %f\n", $end3 - $start3);
echo "---------------------------------------\n";
printf("Total Time: %f\n", $end3 - $start1);
function cmp($a, $b){
if($a['value'] > $b['value']){
return 1;
}else if($a['value'] < $b['value']){
return -1;
}else{
return 0;
}
}
?>
HeapSort.php
<?php
/* Author Jacob Psimos */
function array_heapsort(&$array, $cmp_function, $total){
$total--;
for($i = (integer)($total / 2); $i >= 0; $i--){
_heapify_array($array, $i, $total, $cmp_function);
}
for($i = $total; $i > 0; $i--){
_array_swap($array, 0, $i);
$total--;
_heapify_array($array, 0, $total, $cmp_function);
}
}
function _array_swap(&$array, $a, $b){
$temp = $array[$a];
$array[$a] = $array[$b];
$array[$b] = $temp;
}
function _heapify_array(&$array, $i, $total, $cmp_function){
$left = $i * 2;
$right = $left + 1;
$grt = $i;
if($left <= $total){
$direction = call_user_func($cmp_function, $array[$left], $array[$grt]);
if($direction >= 0){
$grt = $left;
}
}
if($right <= $total){
$direction = call_user_func($cmp_function, $array[$right], $array[$grt]);
if($direction >= 0){
$grt = $right;
}
}
if($grt != $i){
_array_swap($array, $i, $grt);
_heapify_array($array, $grt, $total, $cmp_function);
}
}
?>
QuickSort.php
<?php
/* Source: Google search for 'PHP quicksort', I could not find an author
all I could find was 'Powered by hackerrank.com' -jp */
function array_quicksort(&$array, $left, $right, $cmp_function){
$i = _array_partition($array, $left, $right, $cmp_function);
if($left < $i - 1){
array_quicksort($array, $left, $i - 1, $cmp_function);
}
if($right > $i){
array_quicksort($array, $i, $right, $cmp_function);
}
}
function _array_partition(&$array, $left, $right, $cmp_function){
$pivot = $array[(integer)($left + $right) / 2];
while($left <= $right){
while(call_user_func($cmp_function, $array[$left], $pivot) < 0){
$left++;
}
while(call_user_func($cmp_function, $array[$right], $pivot) > 0){
$right--;
}
if($left <= $right){
_array_swap($array, $left, $right);
$left++;
$right--;
}
}
return $left;
}
?>