As the main PHP developer (and as a teacher myself), I never had a reason to know or understand the algorithms behind things like sorting algorithms, except that quicksort is on average faster, and usually it's a PHP sorting algorithm.
But I will have an interview soon, and they recommend understanding basic algorithms like this. So I opened http://www.geeksforgeeks.org/quick-sort/ and implemented my own QuickSort and Partition functions, for practice, of course, to sort the array by one of the values, I came up with this (I use PHP 7.1, so a fair bit syntax is relatively new)
function Partition(array &$Array, $Column, int $Low, int $High): int {
$Pivot = $Array[$High][$Column];
$i = $Low - 1;
for ($j = $Low; $j <= $High - 1; $j++) {
if ($Array[$j][$Column] > $Pivot) {
$i++;
[$Array[$i], $Array[$j]] = [$Array[$j], $Array[$i]];
}
}
[$Array[$i + 1], $Array[$High]] = [$Array[$High], $Array[$i + 1]];
return $i + 1;
}
function QuickSort(array &$Array, $Column, int $Low = 0, ?int $High = null): void {
$High = $High ?? (count($Array) - 1);
if ($Low < $High) {
$PartitionIndex = Partition($Array, $Column, $Low, $High);
QuickSort($Array, $Column, $Low, $PartitionIndex - 1);
QuickSort($Array, $Column, $PartitionIndex + 1, $High);
}
}
! ! , , PHP , C (, usort). , , .
, !
$Tries = 1000;
$_Actions = $Actions;
$Start = microtime(true);
for ($i = 0; $i < $Tries; $i++) {
$Actions = $_Actions;
usort($Actions, function($a, $b) {
return $b['Timestamp'] <=> $a['Timestamp'];
});
}
echo microtime(true) - $Start, "\n";
$Start = microtime(true);
for ($i = 0; $i < $Tries; $i++) {
$Actions = $_Actions;
QuickSort($Actions, 'Timestamp');
}
echo microtime(true) - $Start, "\n";
1.274071931839
0.87327885627747
.
- , , ? usort
quicksort? , ( /, )?
, - QuickSort PHP, , , , usort
. (, , )
function array_column_sort_QuickSort_desc(array &$Array, $Column, int $Start = 0, int $End = null): void {
$End = $End ?? (count($Array) - 1);
$Stack = [];
$Top = 0;
$Stack[$Top++] = $Start;
$Stack[$Top++] = $End;
while ($Top > 0) {
$End = $Stack[--$Top];
$Start = $Stack[--$Top];
if ($Start < $End) {
$Pivot = $Array[$End][$Column];
$PartitionIndex = $Start;
for ($i = $Start; $i < $End; $i++) {
if ($Array[$i][$Column] >= $Pivot) {
[$Array[$i], $Array[$PartitionIndex]] = [$Array[$PartitionIndex], $Array[$i]];
$PartitionIndex++;
}
}
[$Array[$End], $Array[$PartitionIndex]] = [$Array[$PartitionIndex], $Array[$End]];
$Stack[$Top++] = $Start;
$Stack[$Top++] = $PartitionIndex - 1;
$Stack[$Top++] = $PartitionIndex + 1;
$Stack[$Top++] = $End;
}
}
}