Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Zbyt wolny skrypt losowania
Forum PHP.pl > Forum > Przedszkole
emzetka
Witam. Mam problem ze skryptem losowania. Zrobiłem można powiedzieć "pseudo kod", bo na pewno nie jest to tak jak ma być. Chodzi mi mianowicie o wylosowanie trzech liczb z danego przedziału przy czym żadna z nich nie może być taka sama jak pozostałe. Dane powinny być zamieszczone w tablicy. Mi osobiście udało się to, bo kod działa, jednak nie wiem czemu, ale zależy na jakim serwerze. Na jednym jest wszystko ok, a na innym strona wczytuję się strasznie długo (biały ekran) aż wyświetla się błąd, że za długo musiał oczekiwać w jednej z linii kodu losowania.

Bardzo proszę o podpowiedź jak to powinno wyglądać aby działało szybko i nie sprawiało żadnych problemów ?
Oto kod:
  1. function losuj()
  2. {
  3. $randnum[0] = mt_rand(0, $this->numberofr);
  4.  
  5. do{
  6. $randnum[1] = mt_rand(0, $this->numberofr);
  7. }while($randnum[0] == $randnum[1]);
  8.  
  9. do{
  10. $randnum[2] = mt_rand(0, $this->numberofr);
  11. }while($randnum[2] == $randnum[1] || $randnum[0] == $randnum[2]);
  12.  
  13. return $randnum;
  14. }


Z góry dziękuję za odpowiedzi, pozdrawiam.
toaspzoo
skorzystaj z funkcji rand i array_rand
gino
Co przyjmuje zmienna $this->numberofr ?
Podstawiłem do tej funkcji liczby 10 cyfrowe i działa ok, wykonanie poniżej sekundy. Jak duże liczby przyjmuje ta zmienna ?

gino

@toaspzoo rand jest czterokrotnie wolniejsza od mt_rand
toaspzoo
Cytat
@toaspzoo rand jest czterokrotnie wolniejsza od mt_rand


A array_rand ?
Zyggmunt
Przypomniałem sobie, że mam jednak tutaj użytkownika.

Cytat(gino @ 31.05.2011, 17:50:12 ) *
Co przyjmuje zmienna $this->numberofr ?
Podstawiłem do tej funkcji liczby 10 cyfrowe i działa ok, wykonanie poniżej sekundy. Jak duże liczby przyjmuje ta zmienna ?


Przyjmuje liczbę wierszy pobraną z bazy mysql. Bardzo duża na pewno nie jest, pewnie trochę ponad 100.

Pozdrawiam.

P.s. Może dodam cały kod pliku (moduł ma za zadnie pobieranie danych z bazy mysql, które zapisał tam komponent DJ Catalog 2)

  1. <?php defined('_JEXEC') or die('Restricted access');
  2. class get_records
  3. {
  4. var $numberofr, $result;
  5.  
  6. function get_records()
  7. {
  8. $query="SELECT * FROM jos_djc2_items";
  9. $this->result = mysql_query($query);
  10. $this->numberofr = mysql_numrows($this->result); //number of rows
  11. $this->numberofr--;
  12. }
  13.  
  14. function get_datas()
  15. {
  16. $randomnumber = $this->losuj();
  17. for($i = 0 ; $i < 3 ; $i++)
  18. {
  19. $data[$i]["image"] = mysql_result($this->result, $randomnumber[$i], "image_url");
  20. $data[$i]["name"] = mysql_result($this->result, $randomnumber[$i], "name");
  21. $cat_id = mysql_result($this->result, $randomnumber[$i], "cat_id");
  22. $id = $randomnumber[$i] + 3;
  23. //$cat_id++;
  24. $data[$i]["link"] = 'index.php?option=com_djcatalog2&view=item&id='.$id.'&cid='.$cat_id.'&Itemid=568';
  25. $cat_id = $cat_id - 3;
  26. $query = "SELECT * FROM jos_djc2_categories";
  27. $result2 = mysql_query($query);
  28. $data[$i]["cat_name"] = mysql_result($result2, $cat_id, "name");
  29. }
  30.  
  31. return $data;
  32.  
  33. }
  34.  
  35. function losuj()
  36. {
  37. $randnum[0] = mt_rand(0, $this->numberofr);
  38.  
  39. do{
  40. $randnum[1] = mt_rand(0, $this->numberofr);
  41. }while($randnum[0] == $randnum[1]);
  42.  
  43. do{
  44. $randnum[2] = mt_rand(0, $this->numberofr);
  45. }while($randnum[2] == $randnum[1] || $randnum[0] == $randnum[2]);
  46.  
  47. return $randnum;
  48. }
  49.  
  50. }
  51. ?>



EDIT.

Już wszystko działa, przynajmniej u mnie. Nie wiem jednak dlaczego, ale osoba, której robię ten skrypt mówi, że na Firefoxie dalej mu nie działa (mimo, że u mnie wszystko jest ok na każdej przeglądarce).

Co może być tego przyczyną ?

Ma ktoś jakiś pomysł ?
toaspzoo
powod to jego kłamstwo
Zyggmunt
Mówi, że gdy włączy przeglądarkę i pierwsze co zrobi to wejdzie na tą stronę z modułem, to nie działa (biały ekran podczas wczytywania, po 80 sek przestaje i ten biały ekran zostaje - nie wyświetla się żaden błąd), jednak gdy wejdzie najpierw na inną podstronę i później wróci do miejsca gdzie jest moduł to działa. Czy to możliwe ? Jeśli tak to jaka może być tego przyczyna ?

Prosiłbym jeszcze o spróbowanie zrobienia tego samego, czyli wyłączyć przeglądarkę, a po włączeniu wejść od razu tutaj: http://oldtimery.com/index.php?option=com_...&Itemid=323.

Czy jest w ogóle możliwe żeby coś było nie tak gdy nie ma najmniejszego błędu ? Nawet po użyciu:
Kod
ini_set( 'display_errors', 'On' );
error_reporting( E_ALL );


Wyślę jeszcze kod szablonu:
Kod
<?php defined('_JEXEC') or die('Restricted access'); ?>
<div id="katalog_module">
<?php for($i=0; $i < 3; $i++) {?>
<div class="blocks">
  <div class="image">
  <?php $image = explode(".", $dane[$i]["image"]);
  $nazwa_obr = $image[0].'_m.'.$image[1];  
  $link = $dane[$i]["link"];
  echo '<a href="'.$link.'"><img src="http://oldtimery.com/images/djcatalog/'.$nazwa_obr.'" /></a>';  
  ?>  
  </div>

  <div class="name">
  <?php $name = $dane[$i]["name"];  
  echo '<a href="'.$link.'"><p>'.$name.'</p></a>';
  ?>
  </div>

  <div class="category">
  <?php $category = $dane[$i]["cat_name"];  
  echo '<p>('.$category.')</p>';  
  ?>
  </div>
</div>

<?php } ?>

</div>


Co o tym sądzicie ?
Zyggmunt
Zmieniłem całkowicie skrypt losowania i pojawiają się błędy:
Kod
Warning: mysql_numrows(): supplied argument is not a valid MySQL result resource in /home/oldtimery/domains/oldtimery.com/public_html/modules/mod_katalogfirm/helper.php on line 12

Warning: mysql_result(): supplied argument is not a valid MySQL result resource in /home/oldtimery/domains/oldtimery.com/public_html/modules/mod_katalogfirm/helper.php on line 20


Jednak po odświeżeniu już wszystko działa. Wygląda na to jakby nie łączyło się na początku z bazą i nie pobierało prawidłowo zapytania do zmiennej $result. Moduł oparty jest o Joomla jeśli to coś zmienia.

aeaeae
  1. do{
  2. $randnum[1] = mt_rand(0, $this->numberofr);
  3. }while($randnum[0] == $randnum[1]);


Tak się nie robi! thumbsdownsmileyanim.gif
Co jakbyś miał losować w ten sposób 999'999 różnych liczb spośród 1'000'000? Teoretycznie ta pętla może się wykonywać w nieskończoność (a php ma mało czasu ...). Jasne, że dla podanego przykładu można zastosować inną metodę i wylosować jedną liczbę, którą się odrzuci, ale nie zawsze wiadomo co i z czego będzie losowane ...

Spróbuj tak (jeśli wynik może być posortowany, bo jeśli nie może to pokombinujemy dalej ...):
  1. <?php
  2. define('MAX',20); //>=1
  3. define('ILE',10); //ILE<=MAX
  4. for($i=0;$i<=ILE-1;$i++)
  5. {
  6. $t[$i]=rand(1,MAX-$i);
  7. for($j=0;$j<$i;$j++)
  8. if($t[$i]>=$t[$j])
  9. $t[$i]++;
  10. sort($t);
  11. }
  12. for($i=0;$i<=ILE-1;$i++)
  13. echo $t[$i].'<br />';
  14. ?>
Zyggmunt
No właśnie problem jest taki, że ja już zmieniłem skrypt losowania na:
Kod
function losuj()
{
$numbers = range(3, $this->numberofr);
shuffle($numbers);
return array_slice ($numbers,0,3);
}


I widać zmianę, ponieważ teraz strona się wczytuje, ale pojawiają się błędy takie jak podałem wyżej. Dziwne, że gdy stronę się odświeży, to już działa normalnie.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.