SORU
22 EYLÜL 2009, Salı


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 Persons 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
22 EYLÜL 2009, Salı


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"

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • eyes4beautee

    eyes4beautee

    17 HAZİRAN 2011
  • Joanna Okrajni

    Joanna Okraj

    4 EYLÜL 2010
  • Submissions101

    Submissions1

    23 ŞUBAT 2007