php performance

¿Sufriría el rendimiento al usar autocarga en php y buscar el archivo de clase?



performance (7)

Autoload es una gran característica PHP que te ayuda mucho ... El rendimiento no sufrirá si usas la taxonomía inteligente como: 1. toda biblioteca permanece en las carpetas "paquetes" 2. cada clase se encuentra reemplazando el "_" en el nombre de la clase con el "/" y agregando un ".php" al final de la clase = My_App_Smart_Object file = packages / My / App / Smart / Object.php

Los beneficios de este enfoque (utilizado por casi cualquier marco) también es una organización más inteligente de su código :-)

Siempre he luchado con la mejor forma de incluir clases en mi código php. El uso de la ruta es generalmente un problema, pero hace unos minutos encontré esta pregunta que dramáticamente ayuda. Ahora estoy leyendo acerca de __autoload y pensando que podría facilitar el proceso de desarrollo de mis aplicaciones. El problema es que me gusta mantener la estructura de carpetas para separar áreas de funcionalidad en lugar de tirar todo en una carpeta general / lib. Entonces, si anulo la carga automática para hacer una búsqueda profunda de una carpeta de clase que incluya todas las subcarpetas, ¿qué resultados de rendimiento puedo esperar?

Obviamente, esto dependerá de la escala, la profundidad de la estructura de la carpeta y el número de clases, pero generalmente estoy preguntando sobre un proyecto de mediana escala que causará problemas.


Buscar archivos por todos lados hará las cosas más lentas (muchos más golpes de disco). Cargar todas tus clases en caso de que las necesites hará que las cosas te lleven más memoria. Especificar qué clases necesita en cada archivo es difícil de mantener (es decir, no se eliminan si ya no se usan).

La verdadera pregunta es, ¿cuál de estos es más importante para ti? Al final, son intercambios, así que debes elegir uno. Sin embargo, es discutible que la mayor parte de la sobrecarga en la segunda y tercera opción tenga que ver con la compilación del código. Usar algo como APC puede reducir significativamente los gastos generales de carga y compilación de cada clase en cada carga de página.

Dado el uso de APC, probablemente adoptaría el enfoque de dividir mi código en módulos (por ejemplo, el módulo de interfaz web, el módulo de interacción de base de datos, etc.) y hacer que cada uno de esos módulos importe todas las clases de su módulo, más clases de otros módulos que puedan necesitar. Es un intercambio entre los dos últimos, y he encontrado que funciona lo suficientemente bien para mis necesidades.


El enfoque de Zend Framework es realizar autocarga basándose en el estándar de carpeta PEAR (Class_Foo maps en /Class/Foo.php), sin embargo, en lugar de utilizar una ruta base establecida, utiliza include_path.

El problema con su enfoque es que no hay manera de verificar de antemano si existe un archivo, por lo que la carga automática intentará incluir un archivo que no exista en ninguno de los include_path, error out y nunca otorgue ninguna otra función de autocarga registrada con spl_autoload_register a posibilidad de incluir el archivo

Por lo tanto, una ligera desviación es proporcionar manualmente una matriz de rutas base donde la carga automática puede esperar encontrar las clases configuradas en la forma PEAR y simplemente recorrer las rutas base:

<?php //... foreach( $paths as $path ) { if( file_exists($path . $classNameToFilePath) ) include $path . $classNameToFilePath; } //... ?>

De acuerdo, se realizará una búsqueda, pero para cada carga automática solo se realizarán, en el peor de los casos, búsquedas, donde n es el número de rutas de base que está comprobando.

Pero si sigue teniendo que escanear los directorios de manera recursiva, la pregunta no es "¿La autocarga perjudicará mi rendimiento?", La pregunta debería ser "¿por qué estoy lanzando mis archivos de clase en una estructura aleatoria?" Cumplir con la estructura PEAR le ahorrará muchos dolores de cabeza, e incluso si decide utilizar manualmente sus inclusiones en lugar de carga automática, no habrá forma de adivinar dónde se encuentran los archivos de clase cuando haga sus declaraciones de inclusión.


Hay dos maneras en que puede hacer esto fácilmente: primero, nombre sus clases para que definan la estructura de dónde encontrarlas

function __autoload($classname) { try { if (class_exists($classname, false) OR interface_exists($classname, false)) { return; } $class = split(''_'', strtolower(strval($classname))); if (array_shift($class) != ''majyk'') { throw new Exception(''Autoloader tried to load a class that does not belong to us ( '' . $classname . '' )''); } switch (count($class)) { case 1: // Core Class - matches Majyk_Foo - include /core/class_foo.php $file = MAJYK_DIR . ''core/class_'' . $class[0] . ''.php''; break; case 2: // Subclass - matches Majyk_Foo_Bar - includes /foo/class_bar.php $file = MAJYK_DIR . $class[0] . ''/class_'' . $class[1] . ''.php''; break; default: throw new Exception(''Unknown Class Name ( '' . $classname .'' )''); return false; } if (file_exists($file)) { require_once($file); if (!class_exists($classname, false) AND !interface_exists($classname, false)) { throw new Exception(''Class cannot be found ( '' . $classname . '' )''); } } else { throw new Exception(''Class File Cannot be found ( '' . str_replace(MAJYK_DIR, '''', $file) . '' )''); } } catch (Exception $e) { // spl_autoload($classname); echo $e->getMessage(); } }

O bien, 2, use múltiples autocargadores. PHP> = 5.1.2 Tiene la biblioteca SPL, que le permite agregar múltiples autocargadores. Agregas uno para cada ruta, y lo encontrará en el camino correcto. O simplemente agréguelos a la ruta include y use la spl_autoload predeterminada ()

Un ejemplo

function autoload_foo($classname) { require_once(''foo/'' . $classname . ''.php''); } function autoload_bar($classname) { require_once(''bar/'' . $classname . ''.php''); } spl_autoload_register(''autoload_foo''); spl_autoload_register(''autoload_bar''); spl_autoload_register(''spl_autoload''); // Default SPL Autoloader


Tiendo a usar un enfoque simple donde __autoload () consulta los nombres de una clase de mapeo hash a rutas relativas, que está contenida en un archivo que se regenera usando un simple script que realiza la búsqueda recursiva.

Esto requiere que la secuencia de comandos se ejecute al agregar un nuevo archivo de clase o reestructurar la base de código, pero también evita la "inteligencia" en __autoload () lo que puede llevar a llamadas stat () innecesarias, y tiene la ventaja de que puedo moverme fácilmente archivos dentro de mi base de código, sabiendo que todo lo que necesito hacer es ejecutar una sola secuencia de comandos para actualizar el autocargador.

El script revisa recursivamente mi directorio includes / y asume que cualquier archivo PHP no nombrado en una lista corta de exclusiones (el autocargador mismo, más algunos otros archivos estándar que tiendo a tener) contiene una clase del mismo nombre.


Un patrón común (Pear, Zend Framework como ejemplos ...) es hacer que el nombre de clase refleje la ruta, por lo que Db_Adapter_Mysql estará en /Db/Adapter/Mysql.php, desde algún lugar que se haya agregado a include-path.


__autoload es genial, pero el costo de indicar todos los archivos en una función de búsqueda recursiva es costoso. Es posible que desee ver la construcción de un árbol de archivos para usar en la carga automática. En mi marco, siempre nombro los archivos para sus clases y uso un mapa que se almacena en caché para los datos.

Visite http://trac.framewerk.org/cgi-bin/trac.fcgi/browser/trunk/index.php [ enlace muerto ], comenzando en la línea 68 para tener una idea de cómo se puede hacer esto.

Editar: Y para responder más directamente a su pregunta, sin almacenamiento en caché, puede esperar un golpe de rendimiento en un sitio con tráfico medio a pesado.