Page 1 of 1

[SOLVED] Huge code timing difference: can't understand why

Posted: Thu Mar 10, 2005 10:54 pm
by Ambush Commander
I have two versions of what essentially do the same thing: take an array of values and create an array->key->key = value.

Code: Select all

$code = "\${$iterate[0]}";
		array_shift($iterate);
		foreach ($iterate as $readfile_value) {
			if ($readfile_value == "") {
				$code .= "[]";
			} else {
				$code .= "['$readfile_value']";
			}
		}
		$code .= " = \$data;";
		eval($code);
The second one was suggested by someone else to use references:

Code: Select all

$code =& ${$iterate[0]};
		array_shift($iterate);
		for ($i = 0; isset($iterate[$i]); $i++) {
			if (!isset($code)) {
				$code = array();
			}
			if (isset($iterate[$i+1])) {
				if ($iterate[$i] !== "") {
					$code =& $code[$iterate[$i]];
				} else {
					$code =& $code[];
				}
			} else {
				if ($iterate[$i] !== "") {
					$code[$iterate[$i]] = $data;
				} else {
					$code[] = $data;
				}
			}
		}
When this repeats only, say, 50 times, the difference is neglible. But when I use my huge "readall" script, the first executes in 10 - 20 seconds, and the other one times out (with a max exec of 120 sec).

I can't understand this. Why is the second one taking so long?

BTW: in the sample I'm citing, each of these is repeated about a 2000 times.

Posted: Thu Mar 10, 2005 11:06 pm
by feyd
that doesn't look very much like my example before..

in fact, it's an infinite loop.

Posted: Fri Mar 11, 2005 2:30 pm
by Ambush Commander
But it works on smaller samples. Here's a modified version:

Code: Select all

$code =& ${$iterate[0]};
array_shift($iterate);
for ($i = 0; $i < sizeof($iterate); $i++) {
	if (!isset($code)) {
		$code = array();
	}
	if ($iterate[$i] !== "") {
		$code =& $code[$iterate[$i]];
	} else {
		$code =& $code[];
	}
		
}
$code = $data;
Still times out. Is there some unknown overhead on creating references?

Posted: Fri Mar 11, 2005 2:57 pm
by feyd
care to post the array that takes a while?

Posted: Fri Mar 11, 2005 4:57 pm
by Ambush Commander
I've fixed it now, it was an infinite loop... but I don't think it was in that code. This is the code I use now:

Code: Select all

$code =& ${$iterate[0]};
array_shift($iterate);
for ($i = 0; $i < sizeof($iterate); $i++) {
	if (!isset($code)) {
		$code = array();
	}

	if ($iterate[$i] !== "") {
		$code =& $code[$iterate[$i]];
	} else {
		$code =& $code[];
	}
			
}
$code = $data;
Seems to work fine. However... for some reason, some bad logic elsewhere in the script was triggering an infinite loop when an expected variable was not called. The funny thing was that when the old form was used, the loop didn't occur. It's kinda complicated, but I've fixed that too, so, yeah. The infinite loop idea definitely helped.

Posted: Fri Mar 11, 2005 7:01 pm
by feyd
note: you will have a parse/syntax error if you supply a "blank" in the $iterate array..

Posted: Fri Mar 11, 2005 9:19 pm
by Ambush Commander
An E level error? Because I haven't seen anything from the script yet. Why would I get an error?

Posted: Fri Mar 11, 2005 9:46 pm
by feyd
hmm can't get the error to happen any more for some reason.. anyway it was:
Fatal error: [] operator not supported for strings in debug.php on line 24
line 24 of my test was your

Code: Select all

$code =& $code[];

Posted: Fri Mar 11, 2005 9:52 pm
by Ambush Commander
Oh! I know why!

Code: Select all

$array = "string";
$array[0] = "BANG!";
Will throw that error (I think). This happens when you try overloading a variable. Like:

Code: Select all

$var:furtherdown&gt;Bang
$var:furtherdown:&gt;Boom
Essentially, this is wrong, and would throw an error anyway. Hmm... we could rewrite it:

Code: Select all

$code =& ${$iterate[0]};
array_shift($iterate);
for ($i = 0; $i < sizeof($iterate); $i++) {
    if (!isset($code)) {
        $code = array();
    }
    
    if (is_array($code)) {
      if ($iterate[$i] !== "") {
          $code =& $code[$iterate[$i]];
      } else {
          $code =& $code[];
      }
    } else {
      $code = NULL; //Disable the reference
      break;
    }   
}
$code = $data;
Wow! You're so helpful, even debugging code! Thanks a lot man!