kostenloser Webspace werbefrei: lima-city


DB-Roulette

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    vampiresilence

    Kostenloser Webspace von vampiresilence

    vampiresilence hat kostenlosen Webspace.

    Ich bin gerade dabei eine Art Roulette zu schreiben. Ein PHP-Skript soll an Hand der Häufigkeit eine zufällige ID in der DB wählen und dessen Text ausgeben. Das Problem dabei ist eigtl nur die Gewichtung. Ich könnte mir yetzt mühselig ellenlange hitranges anlegen und arrays schreiben, aber vorher wollte ich mal hier fragen, ob es da nicht noch einen effizienteren Weg gibt. Vorallem soll es schnell ablaufen, denn diese Funktion wird häufig genutzt werden.

    DB-Design:
    ID		Häufigkeit	Text
    1		10		Grün
    2		5		Blau
    3		1		Rot

    Beispiel:
    Das Ergebnis der Funktion soll dann 10 mal häufiger Grün, als Rot sein. Und Blau soll nur halb so häufig ausgeworfen werden, als Grün. Damit meine ich natürlich statistisch. Grundsätzlich sollen die Einträge zufällig gewählt werden.

    Hinweis: Klar könnte ich auch einfach 10 mal "Grün" in die DB eintragen, aber es sollen später noch Häufigkeiten im 4-stelligen Bereich hinzukommen, daher würde das zu einer zu großen Redundanz führen.

    Liebe Grüße
    - VampireSilence

    Beitrag zuletzt geändert: 22.8.2009 23:32:03 von vampiresilence
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hi, ich helf dir mal (sonst tuts ja keiner)

    Zuerst Daten aus DB auslesen, dann:
    $colors = array(); // leeres Array erzeugen
    while($row = mysql_fetch_assoc( $result )) {
        for ($i=0; $i<$row["Haufigkeit"]; $i++) {
            array_push($colors, $row["Text"]); // Eintrag hinten an das Array anhängen
        }
    }
    shuffle($colors); // Array durchmischen
    echo $colors[0]; // Dein zufälliges Ergebnis
  4. Ho, ich habe jetzt zwei Varianten (einmal eine optimierte Variante deines Codes und eine von mir) gebenchmarkt:

    Ich habe ein MySQL-Datenbank mit den Attributen id und p, wobei p eine Zahl zwischen 0 und 10000 ist (also die Häufigkeit).
    Ich habe 255 solcher id - p Zahlenpaare generiert (also ein unsigned tinyint :)

    Jetzt der jeweilige Code mit Ergebnissen:

    $db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
      
      $b=array();
      
      $mtime = microtime();
      $mtime = explode(" ",$mtime);
      $mtime = $mtime[1] + $mtime[0];
      $starttime = $mtime;
      
      $stmt = $db->query("SELECT id, p FROM random");
      $stmt->setFetchMode(PDO::FETCH_ASSOC);
       
      $colors = array();
      while($row = $stmt->fetch()) {
        for ($i=0; $i<$row["p"]; ++$i) {
            array_push($colors, $row["id"]);
        }
      }
      
      $size = count($colors);
      for($i=0;$i<XXXXX;++$i) {
        $r = mt_rand(0, $size-1);
        array_push($b, $colors[$r]);
      }
    
      $mtime = microtime();
      $mtime = explode(" ",$mtime);
      $mtime = $mtime[1] + $mtime[0];
      $endtime = $mtime;
      $totaltime = ($endtime - $starttime);
      echo "This page was created in ".$totaltime." seconds" . "<pre>";
      var_dump($b);

    mit:
    2.25 s für XXXXX = 100000
    1.9s für XXXXX = 10

    $db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
      
      $b=array();
      
      $mtime = microtime();
      $mtime = explode(" ",$mtime);
      $mtime = $mtime[1] + $mtime[0];
      $starttime = $mtime;
      
      $stmt = $db->query("SELECT id, p FROM random");
      $cols = $stmt->fetchAll(PDO::FETCH_ASSOC);
      $size = count($cols);
      
      for($i=0;$i<XXXXX;++$i) {
        $r = mt_rand(0, $size-1);
        if(mt_rand(0,10000)<$cols[$r]['p']) {
          array_push($b, $cols[$r]['id']);
        }
        else {
          --$i;
        }
      }
    
      $mtime = microtime();
      $mtime = explode(" ",$mtime);
      $mtime = $mtime[1] + $mtime[0];
      $endtime = $mtime;
      $totaltime = ($endtime - $starttime);
      echo "This page was created in ".$totaltime." seconds" . "<pre>";
      var_dump($b);


    mit:
    0.6 s für XXXXX = 100000
    0.002 s für XXXXX = 10

    Hätte ich das shuffle statt dem mt_rand genutzt bei erster Version wäre es noch viel schlimmer geworden (max_execution_time...)

    (Und ja, mein PC ist lahm :D)

    Beitrag zuletzt geändert: 23.10.2009 15:07:49 von nikic
  5. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!