Posted by: phillipnb | October 25, 2010

Experimenting with __autoload()


In my last article about ‘__autoload()’, I had recommended that __autoload() is an extremely useful function. A few people who happened to read my blog requested me to be a little more firm about my claim that __autoload() is indeed an useful function. Initially I was not sure whether I should accept this challenge or not. Finally, I decided that I have to conduct a few experiments to prove my claim that __autoload() is indeed an useful function. The next question that anyone who reads this paragraph will have is,” Useful under what circumstances? – is it useful always or is it useful only under certain type of circumstances?”. To answer these questions,let us get our hands dirty – let us test the use of __autoload() under different circumstances. To find if the use of __autoload() is better than not using it,I wrote two php scripts of which one loads class files using __autoload() and the other one loads class files using the ‘require/include’ statement. Then, I measured the time taken to execute these two scripts. These timings are shown in a table below and will help us conclude how useful is this __autoload(). The php code that I used to test my claim is shown below:


[without_autoload.php]

$startTime = microtime(true);

require 'class0.php';
require 'class1.php';
require 'class2.php';
require 'class3.php';
require 'class4.php';

$obj0 = new class0;
$obj1 = new class1;
$obj2 = new class2;
$obj3 = new class3;
$obj4 = new class4;
$endTime = microtime(true);
$totalTime = $endTime - $startTime;


[with_autoload.php]
$startTime = microtime(true);
function __autoload($className)
{
    if (file_exists($className.'.php'))
    {
     require("$className.php");
    }
}
$obj0 = new class0;
$obj1 = new class1;
$obj2 = new class2;
$obj3 = new class3;
$obj4 = new class4;
$endTime = microtime(true);
$totalTime = $endTime - $startTime;

Each class file used in this test looks like this:

class class0
{
function __construct()
  {
    echo "class 0 ";
  }
}

After running the above to scripts, I have collected the time required to execute both these scripts/code. Initially, I have used 5 class files to do this test,then I increased the number of class files to 10 then to 20,50,100,250,500 and 1000. The table below shows the time taken for ‘n’ class files to be loaded first, without using __autoload() and then using __autoload():

Number of class files Without Autoload(ms) With Autoload(ms)
5 0.054713964 0.063755989
5 0.003904819 0.012288094
5 0.004127979 0.008557796
5 0.003885984 0.008503914
5 0.00387001 0.0086481570
10 0.098628044 0.139814138
10 0.046847105 0.020604849
10 0.007612944 0.020073891
10 0.007493019 0.019648790
10 0.008089066 0.016855955
20 0.212351084 0.274940014
20 0.015074015 0.041512966
20 0.015919924 0.044404030
20 0.021837950 0.041507959
20 0.015767097 0.035516024
50 0.547036886 0.752453089
50 0.048346996 0.091141939
50 0.051198006 0.086055040
50 0.052088976 0.101037979
50 0.051561832 0.101820946
100 1.086238146 1.483531952
100 0.134963036 0.179382086
100 0.102601051 0.181129932
100 0.094178915 0.177652121
100 0.093728065 0.308305025
250 2.738711119 3.787230015
250 0.233870983 0.506677866
250 0.244433880 0.473183870
250 0.249101877 0.584417105
250 0.250370979 0.615337849
500 5.455281973 7.607409000
500 0.496469021 1.168529987
500 0.465780020 1.006058931
500 0.495479822 1.050091982
500 0.458348036 1.002222061
1000 11.01507711 15.19992304
1000 1.012890816 1.994160891
1000 1.018293858 2.030622005
1000 0.994281054 1.983510017
1000 1.017564058 2.198755026


Here is the code that will prouduce the required number of class files and the two php files (one that uses the __autoload() and one that does not use __autoload());

echo "\n creating without_autoload.php";
$numClassFiles = 1000;
for ($x = 0; $x < $numClassFiles; $x++)
{
$fp = fopen("class$x.php",'w+');
$fileContent = "<?php \n class class$x \n { function __construct() \n { \n echo \"class $x \\n \"; \n } \n } ";
  if ($fp)
  {
    fwrite($fp,$fileContent);
    fclose($fp);
  }
}
$fp = fopen("without_autoload.php",'w+');
$fileContent = "<?php ";
$fileContent = $fileContent." \n\n \$startTime = microtime(true);";
  for ($x = 0; $x < $numClassFiles; $x++)
  {
    $fileContent = $fileContent."\n require 'class".$x.".php'; ";
  }
$fileContent = $fileContent."\n\n";
  for ($x = 0; $x < $numClassFiles; $x++)
  {
    $fileContent = $fileContent."\n \$obj$x = new class$x;";
  }
  $fileContent = $fileContent."\n \$endTime = microtime(true); \n\n\$totalTime = \$endTime - \$startTime;";
  $fileContent = $fileContent."\n\n echo \" Elapsed time = \$totalTime \";";
  $fileContent = $fileContent."\n\n \$fpt = fopen(\"without_autoload_runtime.php\",'a+');";
  $fileContent = $fileContent."\n \$numFiles = ".$numClassFiles."; \n if (\$numFiles < 10)   ";
  $fileContent = $fileContent."\n { \n \$numFiles = '0'.\$numFiles; \n } \n ";
  $fileContent = $fileContent."\n \$runTimeDetails = \"\\n\". \$numFiles.' '.\$totalTime;   \n";
  $fileContent = $fileContent."\n if (\$fpt) \n { \n fwrite(\$fpt,\$runTimeDetails); \n      
if ($fp)
  {
    fwrite($fp,$fileContent);
    fclose($fp);
  }
  $fp = NULL;
echo "\n Done...";

echo "\n Creating with_autoload.php";

$fp = fopen("with_autoload.php",'w+');
$fileContent = "<?php";
$fileContent = $fileContent." \n\n \$startTime = microtime(true);";
$fileContent = $fileContent."\n function __autoload(\$className) \n { \n if (file_exists(\$className.'.php'))";
$fileContent = $fileContent."\n { \n require(\"\$className.php\"); \n } \n } ";

for ($x = 0; $x < $numClassFiles; $x++)
{
$fileContent = $fileContent."\n \$obj$x = new class$x;";
}
$fileContent = $fileContent."\n \$endTime = microtime(true); \n\n\$totalTime = \$endTime - \$startTime;";
$fileContent = $fileContent."\n\n echo \" Elapsed time = \$totalTime \";";
$fileContent = $fileContent."\n\n \$fpt = fopen(\"with_autoload_runtime.php\",'a+');";
$fileContent = $fileContent."\n \$numFiles = ".$numClassFiles."; \n if (\$numFiles < 10) ";
$fileContent = $fileContent."\n { \n \$numFiles = '0'.\$numFiles; \n } \n ";
$fileContent = $fileContent."\n \$runTimeDetails = \"\\n\". \$numFiles.' '.\$totalTime; \n";
$fileContent = $fileContent."\n if (\$fpt) \n { \n fwrite(\$fpt,\$runTimeDetails); \n fclose(\$fpt); \n }";

if ($fp)
{
fwrite($fp,$fileContent);
fclose($fp);
}
$fp = NULL;
echo "\n Done..";
echo "\n End....";

using five class files

Test using five class files


using five hundred class files

Test using five hundred class files

Conclusion: __autoload() shows no specific advantage if the number of class files that need to be included are small. Also, if you have about 100 class files, the time taken to load these files using __autoload() is more compared to the one where __autoload() is not used. But, one advantage of using __autoload() is that if you use __autoload(), you do not have to write hundreds of ‘include’ or ‘require’ statements. __autoload() is also useful if the decision of which class file needs to be loaded is taken at run-time.

I do not claim that the above results are correct because there could be so many other factors that could have influenced the code execution timings. The above scripts were executed on a machine with the following configuration: Intel Core 2 Duo 2.00 GHz, 3.00 GB of RAM, Windows Vista Home Basic as the operating system.

As usual, please write to me about your comments, objections and suggestions
Till next time, Happy PHP Programming!

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: