avinoamr Posted March 5, 2008 Share Posted March 5, 2008 We had a huge discussion about it at the office, and wanted your advice. Consider a very large-scale MVC web application (over 3000 files, atleast 2000 files in different files), which of the two methods will be more high-performance? (for argument purposes, forget dev-time or complexity, only interested about speed.) 1. Creating a huge array with 'ClassName' => 'ClassPath.php', and then use __autoload to require_once the class definition file according to that array. 2. For each file, write a list of require_once that is required for that script/file/object to fully work? Also keep in mind that the list will include ALL of the files that are needed for that class, regardless of which functions were actually used. What do you think? Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/ Share on other sites More sharing options...
alecks Posted March 6, 2008 Share Posted March 6, 2008 Seems that doing the latter (require_once each time) is a bit faster. Put together some test scripts and made 998 classes, each in their own file, and then timed __autoloading each class and then require_once-ing each class. Here is what I did, specifically. 1. I made a function to generate a file name (and class name) and then looped to make 1000 different php files, and store them in array, name=>file. 2. When it finished making those files, it prints out a string formatted like an array creation string ('something' => 'something else', ...), which I copied to make an array in a new script. 3. For the require_once, I looped through the above array and included each file, immediately afterward adding a new object to an array. 4. I microtimed each file inclusion method individually; here are the results: Note: I had to delete 2 of the classes because they were randomly named 'use' and 'try', which are reserved... I restarted my server after each trial... __autoload each ----------------- 0.115617036819 0.177067041397 0.110083890915 0.134618959427 0.148484945297 require_once each ----------------- 0.124009132385 0.120284080505 0.106649875641 0.103686809542 0.103996038437 Soooo yeah. EDIT: test script stuff class timer { public function timer() { $this->resume = $this->cur_time(); $this->pause = 0; $this->state = TRUE; $this->total = 0; } private function cur_time(){ $time = explode(' ', microtime()); return $time[1].substr($time[0], 1); } public function pause() { if ($this->state) { $this->pause = $this->cur_time(); $this->total = $this->pause - $this->resume; $this->state = FALSE; return $this->total; } } public function resume() { if (!$this->state) { $this->resume = $this->cur_time(); $this->state = TRUE; } } } /* * File gen * function fill($len) { $chars = "abcdefghijkmnopqrstuvwxyz"; $i = 0; while ($i < $len) { $fill = $fill.substr($chars, rand(0,24), 1); $i++; } return $fill; } $huge = array(); $i = 0; while ($i < 1000) { $name = fill(3); if (!file_exists("lots_o_files/".$name.".php")) { $file = fopen("lots_o_files/".$name.".php", "w"); fwrite($file, "<?php class $name { function $name(){} } ?>"); fclose($file); $huge[$name] = $name.".php"; $i++; } } foreach ($huge as $name => $file) { echo "'$name'=>'$file', "; } echo "<br />"; foreach ($huge as $name => $file) { echo "require_once 'lots_o_files/$file';"; } */ // Listed all 998 classes. $classes = array('cmh'=>'cmh.php', 'jnj'=>'jnj.php', 'dur'=>'dur.php', 'hze'=>'hze.php', ....); // __AUTOLOAD TEST $autoload = new timer(); function __autoload($name) { global $classes; require_once 'lots_o_files/'.$classes[$name]; } foreach ($classes as $name => $file) { $class[] = new $name; } echo $autoload->pause(); // REQUIRE ONCE TEST /* $require = new timer(); foreach ($classes as $name => $file) { require_once 'lots_o_files/'.$file; $class[] = new $name; } echo $require->pause(); */ Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-484472 Share on other sites More sharing options...
keeB Posted March 6, 2008 Share Posted March 6, 2008 require_once is the way to go. __autoload is one of those things that is good on paper but goddamn is it hard to debug if issues arise. Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-484577 Share on other sites More sharing options...
aschk Posted March 6, 2008 Share Posted March 6, 2008 What you've failed to take into account in the test is the way that this will work. With __autoload() it is fired every time a class is "not known about". Thus only a require_once is done ONCE for each class. Whereas if you have lots of classes each with their own dependencies (i.e. each class has the files it requires listed in it as in method 2) you have the overhead call of a require_once() for EVERY class file you use, regardless of whether you have already loaded that class or not. Thus the test below is skewed because it implies that a require_once is performed only once (which is not true for the 2nd method). Also from another point of view (and off-topic because you were discussing speed), I personally would HATE to have to know what each file required, and maintaining that in 2000 class files is just ridiculous. __autoload() is a winner in my eyes... Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-484684 Share on other sites More sharing options...
avinoamr Posted March 6, 2008 Author Share Posted March 6, 2008 Thank you Alecks, your method seemed to do the work. Only thing to note though, is that in your test you've included all of the classes, but in-fact __autoload will only include the needed ones. The require_once approach will included all of the files needed throughout the class, __autoload will only create the ones needed by the specific workflow (functions, conditions, etc.). For example, let's consider the following class: class ClassName() { function Func1() { // uses class1.php } function Func2() { // uses class2.php } function Func3() { // uses class3.php } } If we only execute ->Func3(), autoload will only include class3.php, require_once will include all three files. keebB, regarding the debugging issue, I just suggest extremely secure code. The function should throw detailed exceptions about every little issue (class in array, file exists, include failed, class exists, anything else?), making it impossible to miss anything. Overall I agree with aschk, that when it comes to maintainability and rapid development, __autoload is a great tool, even at the expense of a minor performance reduction. Only problem I see with coding practices with __autoload, is that a careless programmer might use too many different classes for simple operations that doesn't really require all of these classes. With require_once you can't miss the fact that you need to use a different class file and with __autoload it's easy to get forgetful. Makes sense? Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-484687 Share on other sites More sharing options...
avinoamr Posted March 6, 2008 Author Share Posted March 6, 2008 Using alecks' test results, I did some math. The avg. time with __autoload() was 0.137174374771 The avg. time with require_once() was 0.111725187302 This means under the test conditions (loading the exact same files), __autoload() is 22.778% slower. Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-484728 Share on other sites More sharing options...
deadonarrival Posted March 6, 2008 Share Posted March 6, 2008 <? // Constants: define ('DIRSEP', DIRECTORY_SEPARATOR); // Get site path $site_path = realpath(dirname(__FILE__) . DIRSEP . '..' . DIRSEP); define ('SITE_PATH', $site_path); function __autoload($class_name) { $filename = strtolower($class_name) . '.class.php'; $file = SITE_PATH . 'classes' . DIRSEP . $filename; if (file_exists($file) == false) { return false; } include ($file); } ?> That's my autoload class - all it does is every time I type $var = new {classname}; It automatically loads classes/classname.class.php, no need for an array. Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-485053 Share on other sites More sharing options...
Daniel0 Posted March 6, 2008 Share Posted March 6, 2008 require_once is the way to go. __autoload is one of those things that is good on paper but goddamn is it hard to debug if issues arise. Why would it be difficult to debug? Quote Link to comment https://forums.phpfreaks.com/topic/94596-autoload-vs-require_once-performance-wise/#findComment-485175 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.