Tom: Noch mehr Zufälle

Beitrag lesen

Hello Globe, hello@all

ich bin das nochmal durchgegangen, habe den Längenfehler in meiner Triviallösung beseitigt und die while()-Schleife gegen eine for()-Schleife ausgetauscht. der Test auf dem Wampp ergab dann aber merkwürdige Ergebnisse:

<?php

/**
 * author: globe
 * lector: tom
 * siehe http://forum.de.selfhtml.org/my/?t=187722&m=1248486

#------------------------------------------------------------------------------
 #
 # Generiere zufällige (alphanumerische) Zeichenfolge aus den Bereichen a-z, A-Z, 0-9
 # @param integer $min minimale Anzahl an Zeichen
 # @param integer $max maximale Anzahl an Zeichen (optional)
 # @param array $additionalCharacters zusätzliche
 # @return string zufällige Zeichenkette
 */
function randomString( $min, $max=null, $additionalCharacters=array() )
{
    // baue alphanumerisches character-array nur einmal für alle folgenden aufrufe
    static $characters = null;

if( $characters === null )
    {
        $characters = array_merge(
            range( 'a', 'z' ), // kleinbuchstaben
            range( 'A', 'Z' ), // grossbuchstaben
            range( 0, 9 ) // zahlen
        );
    }

// füge zusätzliche zeichen ein
    $c = $additionalCharacters ? array_merge( $characters, $additionalCharacters ) : $characters;

// ermittle länge des zufallstrings
    $length = is_numeric($max) && $min != $max ? mt_rand( $min, $max ) : $min;

// ermittle zufällige indexe aus dem character-array
    $indexes = array_rand( $c, $length );

// ziehe zeichen zu jeweiligem index aus dem character-array
    $t = array();

foreach( $indexes as $i )
    {
        $t[] = $c[ $i ];
    }

// füge einzelne zeichen zu einem string zusammen
    return join( $t );
}

#------------------------------------------------------------------------------

function get_random_str($lenmin, $lenmax, $extra='')
{
  #mt_srand ((double)microtime()*1000000);  ## ? ist das noch notwendig?
  $anzahl = mt_rand($lenmin,$lenmax);

$zeichen="abcdefghijklmnopqrstuvwxyzäöüßABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ0123456789-+_&~.,!".$extra;

$zufall="";

$i=0;
  for ($i = 0; $i < $anzahl; $i++)
  {
    $zufall .= substr($zeichen, mt_rand(0,strlen($zeichen)-1),1);
  }

return $zufall;
}
#==============================================================================

php main

#==============================================================================
echo '<pre>';

$runs = 10000;

$start = microtime(true);

$t = array();
for( $i=0; $i < $runs; $i++ )
{
    $t[] = randomString( 10 );
}

$end = microtime(true);
echo 'randomString() took ', $end - $start, ' seconds and generated ', count( array_unique( $t ) ), ' unique strings in ', $runs, ' runs', "\n";

#-----------------------

$start = microtime(true);

$t = array();
for( $i=0; $i < $runs; $i++ )
{
    $t[] = get_random_str( 10, 10 );
}

$end = microtime(true);
echo 'get_random_str() took ', $end - $start, ' seconds and generated ', count( array_unique( $t ) ), ' unique strings in ', $runs, ' runs', "\n";

echo '</pre>';

?>

1. Durchlauf:

randomString() took 0.505483865738 seconds and generated 559 unique strings in 10000 runs
    get_random_str() took 0.520390033722 seconds and generated 10000 unique strings in 10000 runs

2. Durchlauf:

randomString() took 0.470019102097 seconds and generated 559 unique strings in 10000 runs
    get_random_str() took 0.521300077438 seconds and generated 10000 unique strings in 10000 runs

3. Durchlauf

randomString() took 0.528935909271 seconds and generated 559 unique strings in 10000 runs
   get_random_str() took 0.467758178711 seconds and generated 10000 unique strings in 10000 runs

Wieso erzeiugt die Array-Lösung bei mir immer 559 unique Strings?

Das Geheimnis wird wohl in array_rand() liegen.
Ich habe noch nicht in den Quelltext geschaut, wie das nun wieder den Parameter num_req umsetzt.
http://de3.php.net/manual/en/function.array-rand.php

Ich hätte intuitiv das gesamte Array verwürfelt und dann nur die $len Stück in der foreach-Schliefe ausgeschnitten, also foreach bei $len abgebrochen.

Der Bremser in der String-Lösung war aber eindeutig die while()-Schleife

[Zur OOP-Lösung hätte ich dann auch noch einige Frägelchen. Allerdings habe ich es dort mit meinen Umbauten im Moment nur geschafft, dass sie mir immer den Apachen runterfährt *g*. dauert also noch, weil mich DIE Ursache nun erstmal interessiert]

Liebe Grüße aus dem schönen Oberharz

Tom vom Berg

--
Nur selber lernen macht schlau
http://bergpost.annerschbarrich.de