php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #14237 reference calls in some cases very slow
Submitted: 2001-11-26 11:26 UTC Modified: 2003-06-08 15:34 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: alberty at neptunelabs dot com Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5.0.0-dev OS: i686-pc-linux-gnu
Private report: No CVE-ID: None
 [2001-11-26 11:26 UTC] alberty at neptunelabs dot com
Hi, i have found a very critical behavior with references under php.
The usage of references push in some cases the execution time extremly
higher.
I have written a small php script to explain the problem.
The main problem is, the longer the string the higher the execution
time, if you use a reference to the string.


<?php

// a function with using a reference to a parameter
function with_reference (&$stream, $loopcounter){
	for ($x=0;$x < $loopcounter; $x++){
		$xyz=substr($stream,0,5); // i take only the first 5 characters
	}
}


// the same function, but without a reference
function without_reference ($stream, $loopcounter){
	for ($x=0;$x < $loopcounter; $x++){
		$xyz=substr($stream,0,5);
	}
}


set_time_limit(60);

$loopcount=100; // only 100 function calls!
$streamsize=1048576; // 1MB, the longer the slower!!! Try 2MB.

// First, made a big string
for($x=0,$stream='';$x<$streamsize;$x++,$stream.='x'){}

// Start function with a reference and measure start time
$tmp = explode(' ', microtime()); $measure['Start Reference']=(double)$tmp[0] + (double)$tmp[1];
with_reference ($stream, $loopcount);

// Start function without a reference
$tmp = explode(' ', microtime()); $measure['Start Normal']=(double)$tmp[0] + (double)$tmp[1];
without_reference ($stream, $loopcount);

// measure end time
$tmp = explode(' ', microtime()); $measure['End']=(double)$tmp[0] + (double)$tmp[1];

// subtract times
$with_ref_sec=$measure['Start Normal']-$measure['Start Reference'];
$without_ref_sec=$measure['End']-$measure['Start Normal'];

// output the times
echo "<tt>";
echo "Loopcount: $loopcount<br>";
echo "String size: $streamsize<br>";

echo "Time for function request \"with_reference\"&nbsp;&nbsp;&nbsp;: ";
echo $with_ref_sec;
echo " secs<br>";

echo "Time for function request \"without_reference\": ";
echo $without_ref_sec;
echo " secs<hr>";

echo "execution time of without_reference is <b>".round($with_ref_sec/$without_ref_sec)."</b> times fast as with_reference!</tt>";
?>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-12-12 19:58 UTC] yohgaki@php.net
Output from Linux Celeron 433/384MB/PHP 4.1.0/Apache 1.3.22.

Loopcount: 100
String size: 1048576
Time for function request "with_reference"   : 1.6308959722519 secs
Time for function request "without_reference": 0.0011709928512573 secsexecution time of without_reference is 1393 times fast as with_reference! 

There must be something wrong....

 [2001-12-12 19:59 UTC] yohgaki@php.net
PHP Version updated to 4.1.0
 [2001-12-12 20:06 UTC] mfischer@php.net
That's a known issue with the current Zend Engine.

We could move it to a ZE feature request, but will it change anything soon? I doubt ...
 [2001-12-13 04:47 UTC] alberty at neptunelabs dot com
I think, this is an very annoying behavior of the zend engine and also there are no warning or clue in the documentation.
Someone must change it.
 [2002-01-31 05:12 UTC] bs_php at infeer dot com
I did some benchmark tests on loops and so that also delever some strange results. 

See it run at: http://phpxpath.sourceforge.net/benchmark/phpBench.php 
Code at: http://phpxpath.sourceforge.net/benchmark/phpBench.php.txt
 [2003-01-04 11:37 UTC] andrey@php.net
 I modified the script a bit by adding var_dump(microtime())
around the function calls. The output :
With reference:
string(21) "0.58075200 1041701482"
string(21) "0.20217700 1041701490"
Without reference:
string(21) "0.20247500 1041701490"
string(21) "0.20739800 1041701490"

as everyone may see without reference is faster as it has to be (according to some docs). I think that there is something wrong in the way the script computes the time.
Ooops, I found it :
$tmp = explode(' ', microtime());
$measure['Start Reference']=(double)$tmp[0] + (double)$tmp[1];
the indexes are swapped must be
$measure['Start Reference']=(double)$tmp[1] + (double)$tmp[0];

Closing this.
 [2003-03-01 16:15 UTC] alberty at neptunelabs dot com
I've seen you have close this bug report with an absolute
strange argument.

A switching of two double values in an addition have no 
consequences for the sum.

There is no problem with the time between the tests.

Why do you don't test the example script and why do you
close this bug report without any questions, although many
people have also report this behavior?

Reopen, and please, don't touch any bug reports before you
check the consequences.
 [2003-06-08 15:34 UTC] zeev@php.net
This is intended behavior.  When you pass by reference, the value that is passed can not be optimized using the refcount mechanism, and if it is passed in turn to other functions (in this case, substr()), it has to be duplicated.  Passing by reference is, in general, slower than passing by value.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue May 07 15:01:36 2024 UTC