seth: Alternative fuer eval(); gesucht ...

Beitrag lesen

gudn tach!

Das mit der Zeiteinsparung kaufe ich Dir so einfach nicht ab,
da solltest Du schon eine Demoseite dazu machen.

bitteschoen:
(allerdings weiss ich nicht, inwiefern solche php-benchmarks aussagekraeftig sind, zumal ich keine ahnung habe, wie bspw. funktionsaufrufe intern gehandhabt werden und was intern optimiert wird und was nicht.)

<?php  
require_once('Benchmark/Timer.php');  
  
function get_AND($A){  
    $out = 1;  
    foreach($A as $val) {  
        switch($val) {  
            case '!1':  $out *= 0;  break;  
            case '!0':  $out *= 1;  break;  
            default:    $out *= $val;  
        }  
    }  
    return $out;  
}  
  
function get_OR($A) {  
    $out = 0;  
    foreach($A as $val) {  
        $out += $val;  
    }  
    return $out;  
}  
  
function unden($a){  
  foreach($a as $v)  
    if($v===0 || $v==='!1') return(false);  
  return(true);  
}  
  
function odern($a){  
  foreach($a as $v)  
    if($v===1 || $v==='!0') return(true);  
  return(false);  
}  
  
$O=array(0, 0, 0);  
$A=array(0, 0, '', '');  
  
$timer = new Benchmark_Timer;  
echo 'Norberts kram: '."\n";  
$timer->setMarker('begin_Norbert');  
for($i=0; $i<1000000; ++$i){  
  $O=array(rand(0, 1), rand(0, 1), rand(0, 1));  
  $A=array(rand(0, 1), rand(0, 1), '!'.rand(0, 1), '!'.rand(0, 1));  
  $D = $A;  
  $D[] = get_OR($O);  
  $E = get_AND($D);  
  ($E > 0);  
}  
$timer->setMarker('end_Norbert');  
echo 'needed: '.$timer->timeElapsed('begin_Norbert','end_Norbert')." s\n";  
  
echo 'seths kram: '."\n";  
$timer->setMarker('begin_seth');  
for($i=0; $i<1000000; ++$i){  
  $O=array(rand(0, 1), rand(0, 1), rand(0, 1));  
  $A=array(rand(0, 1), rand(0, 1), '!'.rand(0, 1), '!'.rand(0, 1));  
  (odern($O) && unden($A));  
}  
$timer->setMarker('end_seth');  
echo 'needed: '.$timer->timeElapsed('begin_seth','end_seth')." s\n";  
?>

erzeugt bei mir (466 MHz) die ausgabe:
  Norberts kram:
  needed: 25.188128 s
  seths kram:
  needed: 15.263572 s

1*1*1*0*1 ist immer schneller als jedes if

erstens stimmt das nicht und zweitens hast eine switch-case-geschichte eingebaut und somit in _jedem_ schleifendurchlauf eine bis drei bedingungen _und_ eine zuweisung _und_ eine multiplikation (in get_AND).

und fuer 1+1+0+0+1 gilt IMHO das gleiche

naja, da das array $OR sowieso nur 3 elemente hat, nimmt sich das an dieser stelle nicht viel. dazu kommt, dass bei get_OR() vorausgesetzt wird, dass $OR nur integer enthalte. ok, wenn das so ist, kann man entsprechend die funktion odern() noch entsprechend abaendern.
wenn man ein grosses array $OR haette, waere die abbruch-bei-fund-methode schneller, da im schnitt bloss ungefaehr zwei schleifen-durchlaeufe gemacht werden muessen.

prost
seth