PHP nesne özelliği ile dizi sıralama?
Eğer gibi bir nesne varsa:
class Person {
var $age;
function __construct($age) {
$this->age = $age;
}
}
ve Person
s herhangi bir dizi var
$person1 = new Person(14);
$person2 = new Person(5);
$people = array($person1, $person2);
Kolay bir yolu Person->age
özelliği $people
dizi sıralama var mı?
CEVAP
Soru karşılaştırma geri çağırma yükü nedeniyle usort kullanma verimsizlik hakkında endişeliydi.
Ben aslında olmayan bir özyinelemeli quicksort ile usort eğer bir fark varsa görmek için kullanıyorum kıyasla 2009 yılında bu cevapladı. Olarak çıktı, vardıönemlibu quicksort 3x daha hızlı çalışan fark.
Olarak artık 2015, ben düşündüm de belki yararlı için tekrar bu yüzden aldım kodu hangi tür 15000 nesneleri kullanarak usort ve quicksort ve koştu üzerinde 3v4l.org hangi çalışır üstünde bir sürü farklı PHP sürümleri. Tüm sonuçları burada: http://3v4l.org/WsEEQ
TL;DR: nesneleri hala usort daha hızlı sıralama için olmayan özyinelemeli quicksort standart PHP kullanarak. HHVM ancak kullanımı ve usort kazanır.
----------- ------------ ------------ ------------ ------------ ------------
| Operation | HHVM | php7 | php5.6.3 | 5.4.35 | 5.3.29 |
----------- ------------ ------------ ------------ ------------ ------------
| usort | *0.0678 | 0.0438 | 0.0934 | 0.1114 | 0.2330 |
| quicksort | 0.0827 | *0.0310 | *0.0709 | *0.0771 | *0.1412 |
| | 19% slower | 30% faster | 25% faster | 31% faster | 40% faster |
----------- ------------ ------------ ------------ ------------ ------------
2009 özgün Notlar
Yaklaşık 1,8 saniye içinde usort ve sıralanmış bir 15000 Kişi nesneleri çalıştım.
Karşılaştırma işlev çağrıları eksikliği ile ilgili endişeleriniz gibi, olmayan özyinelemeli Quicksort bir uygulama ile karşılaştırdım. Bu aslında zaman yaklaşık üçte biri, yaklaşık 0.5 saniye koştu.
Burada iki yaklaşım kriterler benim kod
// Non-recurive Quicksort for an array of Person objects
// adapted from http://www.algorithmist.com/index.php/Quicksort_non-recursive.php
function quickSort( &$array )
{
$cur = 1;
$stack[1]['l'] = 0;
$stack[1]['r'] = count($array)-1;
do
{
$l = $stack[$cur]['l'];
$r = $stack[$cur]['r'];
$cur--;
do
{
$i = $l;
$j = $r;
$tmp = $array[(int)( ($l $r)/2 )];
// partion the array in two parts.
// left from $tmp are with smaller values,
// right from $tmp are with bigger ones
do
{
while( $array[$i]->age < $tmp->age )
$i ;
while( $tmp->age < $array[$j]->age )
$j--;
// swap elements from the two sides
if( $i <= $j)
{
$w = $array[$i];
$array[$i] = $array[$j];
$array[$j] = $w;
$i ;
$j--;
}
}while( $i <= $j );
if( $i < $r )
{
$cur ;
$stack[$cur]['l'] = $i;
$stack[$cur]['r'] = $r;
}
$r = $j;
}while( $l < $r );
}while( $cur != 0 );
}
// usort() comparison function for Person objects
function personSort( $a, $b ) {
return $a->age == $b->age ? 0 : ( $a->age > $b->age ) ? 1 : -1;
}
// simple person object
class Person {
var $age;
function __construct($age) {
$this->age = $age;
}
}
//---------test internal usort() on 15000 Person objects------
srand(1);
$people=array();
for ($x=0; $x<15000; $x )
{
$people[]=new Person(rand(1,100));
}
$start=microtime(true);
usort( $people, 'personSort' );
$total=microtime(true)-$start;
echo "usort took $total\n";
//---------test custom quicksort on 15000 Person objects------
srand(1);
$people=array();
for ($x=0; $x<15000; $x )
{
$people[]=new Person(rand(1,100));
}
$start=microtime(true);
quickSort( $people );
$total=microtime(true)-$start;
echo "quickSort took $total\n";
Bunu çok denedim. çok ilginç bir öneri sınıfı __toString
bir yöntem ekleyin ve sıralama kullanmak için(), Sorun, yerine dize sayısal bir sıralama yapmanın yan etkisi aslında sihirli yöntem " diyebilir sıralama, ikinci parametre olarak SORT_STRİNG geçmelidir. Bu tezgaha, düzgün bir şekilde sıralama yapmak için sıfır ile sayılar pad gerekir. Net sonuç bu usort ve özel quickSort hem daha yavaş olmasıydı
sort 10000 items took 1.76266698837
usort 10000 items took 1.08757710457
quickSort 10000 items took 0.320873022079
İşte sıralama için kod () __olabilirdi kullanarak():
$size=10000;
class Person {
var $age;
function __construct($age) {
$this->age = $age;
$this->sortable=sprintf("d", $age);
}
public function __toString()
{
return $this->sortable;
}
}
srand(1);
$people=array();
for ($x=0; $x<$size; $x )
{
$people[]=new Person(rand(1,100));
}
$start=microtime(true);
sort( $people, SORT_STRING);
$total=microtime(true)-$start;
echo "sort($size) took $total\n"
Nesne tarafından Ruby nesneleri bir di...
Sıralama özelliği ile özel Nesne Array...
Nasıl Scala bir dizi sıralama?...
Bir dizi `length` özelliği okuma gerçe...
Sıralama Tarihe Göre Nesne Dizisi Java...