Mitos de la programación… PHP: require vs require_once

Julio 30, 2008 at 9:15 pm (Evangelios de Dioses de Silicio, Libro de Hechizos PHP) (, , , )

Se que más adelante voy a lamentar andar mirando el twitter de phpsenior en lugar de dedicarme a adelantar trabajo atrasado, pero bueh… ya está hecho el daño. Ví este artículo sobre varias curiosidades de PHP y me detuve un segundo sobre uno en particular que me llamó la atención. En uno de los puntos asegura que require es más rápido que require_once… esto es mentira, un mito del mundo PHP… incluso, por alguna razón que desconozco, en las últimas versiones de PHP, require_once funciona de manera más óptima que require. Deben haber estado tweakeandolo, ya que se recomienda el uso de require_once sobre require (para cargar includes que solo deberían cargarse una vez).

De todas maneras, nunca hubo una ventaja en velocidad de procesamiento por usar un keyword u el otro, (salvo recientemente que parece que se optimizo uno y el otro no). Explico porque. Tuve la oportunidad de andar investigando como funciona internamente el zend engine hace un año cuando había mucho revuelo por el tema de los namespaces en php, e inocentemente pense que andar tocando el engine no podía ser tan difícil, solo hacía falta sacarle el polvo a mis habilidades en C… En fín, esa es otra historia.

En teoría no debería haber cambiado mucho la lógica que distingue a require de require_once desde la última vez que la ví. Básicamente, se utiliza una hash table (de las mismas que se usan para los arrays) para recordar que archivos fueron cargados y cargarlos de vuelta cuando se usa require_once. Lo que sucede es que ambos hacen la busqueda del bucket en la hash table, porque tanto require como require_once tienen que anotar que el archivo fue incluido. La busqueda en la hash table es el trabajo pesado ahí, después fallar si se encontro el archivo, no hace diferencia a la performance. En definitiva la diferencia entre require y require_once es minima, no hay ninguna “llamada extra al sistema”, eso es un mito del mundo php.

Ahora, hay muchas “resultados estadisticos” generados por entusiastas del tema que miden el tiempo de ejecución y comparan resultados. Hay algunos que le dan la razón a la versión mito y otros que muestran lo contrario. El problema con estos resultados, como cualquier medición de este estilo, es que hay que tener cuidado en observar bien que es lo que realmente se está midiendo.

Con require y require_once hay un problema en los resultados de la medición: el acceso a disco. Estas operaciones estan sujetas a la disponibilidad del sistema operativo (recordemos que el tiempo de procesador es compartido en sistemas multitarea), y en comparación con los tiempos reales que tarda lo que realmente queremos medir, el tiempo ocupado por el IO es mucho mayor. O sea, los resultados obtenidos son poco estables y poco confiables… pero podríamos salvarlo si evitaramos el acceso a disco.

Para esto algunos a recurrido a los mismos sistemas que se usan en producción para evitar el acceso a disco (APC, memcache, etc), pero estos también son metodos que están sujetos a los caprichos del sistema operativo. Lo mejor sería evitar completamente el acceso a disco… Y hay una manera.

Otro de los features poco usados de PHP son los stream wrappers. Esto te permite crear tipos de “streams”, objetos utilizados en operaciones de IO. En el manual de php hay un ejemplo de stream wrapper que implementa streams para variables globales, y lo interesante es que podemos usarlos con require y require_once. Use este ejemplo del manual de php para hacer un profile de require y require_once que no considere el acceso a disco:

function mean($data) {
    sort($data);
    $error = ceil(count($data) * 0.03);
    $data = array_slice($data, $error, -$error);
    return array_sum($data) / count($data);
}

$n = 1000;

for ($i = 0; $i < $n; $i++) {
    $GLOBALS["var$i"] = '';
}

$times = array();

for ($i = 0; $i < $n; $i++) {
    $file = "var://var$i";
    $start = microtime(true);
    require $file;
    $end = microtime(true);
    $times[] = $end - $start;
}

printf("%f\n", mean($times));

Al correr el test con estos valores los resultados se muestran muy estables. Estos son (en mi computadora):

require: 0.000037 segundos
require_once: 0.000023 segundos

Hacer la prueba para include e include_once me reporta los mismos resultados, como era de esperarse (ya que tampoco hay una diferencia de importancia entre ambos… salvo cuando ocurre un error). Lo que me resulto extraño es encontrar un diferencia a favor de require_once… seguramente deben haber estado realizando mejoras que no se aplicaron por igual… vaya uno a saber… el zend engine es spaghetti code.

Permalink 8 comentarios

Popurrí de webadas – Opus 0×07

Julio 27, 2008 at 2:43 pm (Popurrí de webadas) (, , , , , , , , )

Permalink 2 comentarios

Mitos – Las competencias de programación te aseguran un mejor trabajo

Julio 21, 2008 at 2:41 pm (Filosofia de Toilette) (, )

Curiosamente, de la discusión en los foros de ADVA que quotee varias veces en los posts anteriores, hay otros mitos que vale la pena mencionar. En este caso es el mito de las competencias de programación como un “camino a la fama” o, mejor dicho, un camino hacia un trabajo mucho mejor pago.

En la mencionada discusión surgió, de entre todo el pasticcio de temas que se tocaron, algo al respecto. Acá está mi opinión sobre las competencias de programación:

Rotundamente en desacuerdo con lo que decís. Casi 8 años de experiencia en el mercado me han enseñado ciertas cosas:

  • desconfiar rotundamente de los rockstar coders, son más peligrosos que los cowboy coders
  • las adquisiciones high profile de personal (a través de competencias con gran impacto mediatico, no al nivel de codear que es más bien algo interno de la comunidad) no son más que operaciones de marketing de las empresas
  • la inteligencia emocional es más importante que, o tan importante como, la inteligencia lógico-matemática
  • los cambios radicales no salen de las empresas (salvo que seas Google), más bien del ámbito universitario, y generalmente no produce réditos importantes a sus gestadores

El último punto en realidad corresponde a otro mito, el de la “capacidad innovadora de las empresas grandes de software”.

Permalink Dejar un comentario

Siguiente Página »