|
Posted by Andreas Thiele on 10/05/17 11:23
> I don't see what's the benefit of using:
>
> eval(abind("arr", array("foo", "bar", "baz")));
>
> instead of using:
>
> abind("arr", array("foo", "bar", "baz"));
> ...
abind just returns a string. If you don't apply eval to abind, the variables
$foo, $bar and $baz will not be declared and thus you will get three error
messages instead of the desired result. Indeed I tested my code. It is
working. You will get those three local variables.
But, your example code demonstrates why my suggestion really is no good
idea. Each time my function test is called, the local variable declaration
gets re-evaluated. This is not needed overhead.
> ...
> When you use eval in your code, it must be evaluated before the engine can
> continue the processing of your script. One of the side-effects is that
it's
> much slower as the following test will show:
> ...
Wow, on my machine the eval is more than 100 times slower. Very convincing -
at least at first glance. But I think the code is a little unfair. The php
parser is in advantage. He only has to parse the body of the for statement
once and might reuse it. To be a bit more fair, I'd suggest the following
comparison:
<?php
$b="<br>";
// create a test file with different variables and different values per
variable ...
$f=fopen("./benchdat.php", "w");
for ($i = 0; $i < 10000; $i++) {
fputs($f, "\$foo$i = \"bar$i\";\r\n");
}
fclose($f);
// ... time the 'manual' evalutation ...
$start = array_sum(explode(' ', microtime()));
$f=fopen("./benchdat.php", "r");
while (!feof($f)) {
eval(fgets($f));
}
fclose($f);
$end = array_sum(explode(' ', microtime())) - $start;
echo 'Finished in ', round($end, 5), " seconds".$b;
// ... create the same test file readable by the parser ...
$f=fopen("./benchdat.php", "w");
fputs($f,"<?PHP\r\n");
for ($i = 0; $i < 10000; $i++) {
fputs($f, "\$foo$i = \"bar$i\";\r\n");
}
fputs($f,"?>");
fclose($f);
// ... and time parser performance :)
$start = array_sum(explode(' ', microtime()));
include("./benchdat.php");
$end = array_sum(explode(' ', microtime())) - $start;
echo 'Finished in ', round($end, 5), " seconds".$b;
?>
Now the parser can't remember any statements and has to evaluate each code
line. Things don't look that dramatic anymore.
On my machine 2.5 GHz Pentium the results are:
Finished in 0.16734 seconds
Finished in 0.07572 seconds
so the relationship would roughly be 2 : 1. OK - eval is slower!
So, as mentioned earlier, my idea was not good. But, experimenting with this
benchmark made things a little clearer for me.
Still eval is very much appealing to me, because with eval you can write
functions writing functions, which can be a powerful tool.
For example with the following
<?PHP
function tag($name, $v1, $v2=false) {
if ($v2) { $value = $v2; $attribs = " ".$v1; }
else { $value = $v1; $attribs = ""; }
return "<".$name.$attribs.">".$value."</".$name.">";
}
function make_tag($name) {
return "function $name(\$v1, \$v2=false) { return tag(\"$name\", \$v1,
\$v2); }";
}
eval(make_tag("table"));
eval(make_tag("tr"));
eval(make_tag("td"));
// demo of the defined tag functions
echo table("border=1", tr(td(1).td("John").td(3)).tr("align='center'",
td(4).td(5).td(6)));
?>
you have a very succint notation for html tags and the evals don't cost you
much.
Andreas
(Note: eval != evil :)) )
Navigation:
[Reply to this message]
|