rfc:function_autoloading

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
rfc:function_autoloading [2013/08/30 11:11] – Fix incorrect constant values ircmaxellrfc:function_autoloading [2013/09/03 12:28] – Withdrawn ircmaxell
Line 1: Line 1:
 ====== PHP RFC: Function Autoloading ====== ====== PHP RFC: Function Autoloading ======
  
-  * Version: 0.1+  * Version: 0.2
   * Date: 2013-08-29   * Date: 2013-08-29
   * Author: Anthony Ferrara <ircmaxell@php.net>   * Author: Anthony Ferrara <ircmaxell@php.net>
-  * Status: Draft+  * Status: Withdrawn
   * First Published at: http://wiki.php.net/rfc/function_autoloading   * First Published at: http://wiki.php.net/rfc/function_autoloading
  
Line 76: Line 76:
 php\autoload_register(function($name, $type) { php\autoload_register(function($name, $type) {
     var_dump($name, $type);     var_dump($name, $type);
-    switch ($type) { +    eval("function $name(){}"); 
-        case php\AUTOLOAD_FUNCTION: +    // We don't need a switchsince we only register for functions.
-            eval("function $name(){}"); +
-            break; +
-        case php\AUTOLOAD_CLASS: +
-            eval("class $name {}"); +
-            break; +
-        case php\AUTOLOAD_CONSTANT: +
-            define($name$name); +
-            break; +
-    }+
 }, php\AUTOLOAD_FUNCTION); }, php\AUTOLOAD_FUNCTION);
 foo(); // string(3) "foo" int(2) foo(); // string(3) "foo" int(2)
Line 104: Line 95:
         case php\AUTOLOAD_FUNCTION:         case php\AUTOLOAD_FUNCTION:
             eval("function $name(){}");             eval("function $name(){}");
-            break; 
-        case php\AUTOLOAD_CLASS: 
-            eval("class $name {}"); 
             break;             break;
         case php\AUTOLOAD_CONSTANT:         case php\AUTOLOAD_CONSTANT:
Line 145: Line 133:
 ?> ?>
 </file> </file>
 +
 +==== Performance ====
 +
 +The following benchmarks are all run on a non-debug build compiled with //--disable-all --disable-cgi//. Note that the numbers provided are the average of the 3 fastest runs for a specific test (higher numbers are thrown out).
 +
 +=== Class Loading ===
 +
 +1000 classes were generated, each in a single file. The following test script was used to execute the following tests:
 +
 +<file php benchmark_autoloading.php>
 +<?php
 +spl_autoload_register(function($class) {
 +        require __DIR__ . '/files/' . $class . '.php';
 +});
 +
 +$start = microtime(true);
 +for ($i = 0; $i < 1000; $i++) {
 +        $class = 'test' . $i;
 +        new $class;
 +}
 +$end = microtime(true);
 +
 +echo "Completed in " . ($end - $start) . " seconds\n";
 +?>
 +</file>
 +
 +  * Master's //spl_autoload// loader: average 0.0225 seconds to load 1000 class files.
 +  * Proposed //php\autoload_register// loader: average 0.0219 seconds to load 1000 class files. (called via spl_autoload_register)
 +
 +Therefore, there is no performance regression when autoloading classes (in fact, it is slightly improved, since one additional //zend_function_call// call is removed).
 +
 +=== Functions ===
 +
 +1000 functions were generated and placed in a single file. The following test script was used to test if there was any change to function call time for a defined function:
 +
 +<file php benchmark_functions.php>
 +<?php
 +require_once 'functions.php';
 +
 +$start = microtime(true);
 +for ($i = 0; $i < 1000; $i++) {
 +        $func = 'test' . $i;
 +        $func();
 +}
 +$end = microtime(true);
 +
 +echo "Completed in " . ($end - $start) . " seconds\n";
 +?>
 +</file>
 +
 +  * Master: average 0.000216 Seconds to call 1000 functions
 +  * Proposal: average 0.000218 Seconds to call 1000 functions
 +
 +
 +Therefore, there is no performance regression to normal function calls (defined functions). The margin of error for this test was on the order of +-0.00004 seconds.
 +
 +=== Constants ===
 +
 +1000 constants were generated and placed in a single file. The following test script was used to test if there was any change to function call time for a defined function:
 +
 +<file php benchmark_constants.php>
 +<?php
 +require_once 'constants.php';
 +
 +$start = microtime(true);
 +for ($i = 0; $i < 1000; $i++) {
 +        $name = 'test' . $i;
 +        constant($name);
 +}
 +$end = microtime(true);
 +
 +echo "Completed in " . ($end - $start) . " seconds\n";
 +?>
 +</file>
 +
 +  * Master: average 0.000228 Seconds to call 1000 constants
 +  * Proposal: average 0.000221 Seconds to call 1000 constants
 +
 +Therefore, there is no performance regression to normal constant lookups (defined constants).
  
 ==== Userland Backwards Compatibility ==== ==== Userland Backwards Compatibility ====
Line 194: Line 261:
  
 It is more of a "why not" question. Supporting multiple types of autoloaded constructs in a single callback can result in a more flexible architecture for end users. It is more of a "why not" question. Supporting multiple types of autoloaded constructs in a single callback can result in a more flexible architecture for end users.
 +
 +==== What Filename Conventions Does This Support? ====
 +
 +None, and all. This proposal presently implements no type of file loading handler.
 +
 +The only thing that is implemented is the ability to register a callback to attempt to load a function or constant (or class) when it is missing. How the callback maps structures to files is outside of the scope of this RFC.
 +
 +==== Doesn't This Complicate The Engine? ====
 +
 +Nope! The reason is that the current autoloading mechanism for classes is extremely fragile as is.
 +
 +For example, the implementation hinges on a global variable which sets the php-level callback to call on autoload. This requires setting up a //zend_fcall_info// struct, and a //zend_fcall_info_cache// struct, as well as dispatching a function internally to autoload. [[https://github.com/php/php-src/blob/9e17094cf4dde60432569246a9a59e48783530bb/Zend/zend_execute_API.c#L1066|The Current Implementation]].
 +
 +The implementation of //spl_autoload_call// and //spl_autoload_register// are also extremely complicated. [[https://github.com/php/php-src/blob/9e17094cf4dde60432569246a9a59e48783530bb/ext/spl/php_spl.c#L466|The current SPL implementation]].
 +
 +This refactor cleans both of these pieces up significantly.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 301: Line 384:
  
   * 2013-08-29 0.1 Initial Creation   * 2013-08-29 0.1 Initial Creation
 +  * 2013-08-30 0.2 Add performance section and basic benchmarks
rfc/function_autoloading.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1