usort vs array_multisort

Winer

Мимо проходил
usort vs array_multisort

возникла проблема сортировки массива вида - array[key](i=1..n, key-ключи) - по произвольному ключу.
Т.е. например массив
PHP:
$arr[0]['key1']=1;
$arr[0]['key2']=5;
$arr[1]['key1']=3;
$arr[1]['key2']=3;
$arr[2]['key1']=2;
$arr[2]['key2']=8;
примет вид:
PHP:
$arr[0]['key1']=1;
$arr[0]['key2']=5;
$arr[1]['key1']=2;
$arr[1]['key2']=8;
$arr[2]['key1']=3;
$arr[2]['key2']=3;
;
"придумал" два способа
1. просто использовать свою функцию сортировки в usort()
PHP:
function mysort($a,$b)
{
	GLOBAL $sortby;
	return strnatcmp($a[$sortby],$b[$sortby]);
};
$sortby='key1';
usort($arr,'mysort');
2.поставить первым ключ по которому сортирую(т.к. array_multisort сортирует только по первому ключу), отсортировать array_multisort и вернуть ключи как были, т.е. имеем два пробегания по массиву+сортировка.
PHP:
$sortby=array('key2','key1');
$sortc=count($sortby);

for($i=0;$i<$test_count;$i++)
{
    for($j=0,$tmparr=array();$j<$sortc;$j++)
   {
	$tmparr[$sortby[$j]]=$test_arr[$i][$sortby[$j]];
   };
   $test_arr[$i]=$tmparr;
};

array_multisort($test_arr);

$sortby=array('key1','key2');
for($i=0;$i<$test_count;$i++)
{
	for($j=0,$tmparr=array();$j<$sortc;$j++)
	{
		$tmparr[$sortby[$j]]=$test_arr[$i][$sortby[$j]];
	};
	$test_arr[$i]=$tmparr;
};
на тесте(массив в 1000 элементов (элемент - array('key1'=>mt_rand(),'key2'=>...))
первый способо оказался медленне - в среднем 0,17 секунд против 0,148 у второго.
Может ли быть такое, мне казалось второй способ медленне будет. И можно ли как-то улучшить второй способ???
А может есть ещё более быстрые способы ???
 

Demiurg

Guest
Может, а может еще иэто и от количества элементов зависит.
Но первый явно выглядит лучше, хотя от глобала стоит избавиться.
 

Winer

Мимо проходил
.des. хм, не подумал насчёт избранного, thanks, буду изучать

-~{}~ 13.05.04 02:42:

изучил, оказалось поучительно :)
сделал ещё несколько тестов( увеличил кол-во элементов до 5000 и 10000). скорость usort падаёт почти линейно, в 5 и 12 по сравнению с 1000 элементов соотвественно.Скорость при обмене ключей и array_multisort падает очень нелинейно, в 11,5 и 33 раза соотвественно, что в принципе естественно - видимо расходы на перегонку массивов туда-сюда очень сильно перекрывают "доходы" от array_multisort :)
вывод - прежде чем радоваться, перепроверь как следует!!!

-~{}~ 13.05.04 13:49:

после некоторых раздумий придумалось следующее:
при заполнении массива делаем ключ 'sortkey', который стоит первым и его значение равно значению ключа, по которому сортируем - $arr[0]=array('sortkey'=>'val2','key1'=>'val1','key2'=>'val2',..),$arr[1]=...
после просто делаем array_multisort и удаляем ключ с помощью array_walk и array_splice.
результаты получились следующие - на массиве из 10 тыс. элементов в среднем скорость получилась 0.8 с.(duron 750,128mb,win2k)
плюсы: изящность кода, скорость, минусы - лишние данные
поправьте, если я не прав в чём-то

-~{}~ 13.05.04 13:50:

да, вот пример кода
PHP:
function mysplice(&$val,$k)
{
	array_splice($val,'sortkey',1);
};
array_multisort($test_arr);
array_walk($test_arr,'mysplice');
-~{}~ 13.05.04 14:16:

и не изобретаю ли я велосипед ???
 
Сверху