2009-12-16 10 views
6

Veo una gran disminución del rendimiento en una secuencia de comandos PHP (línea de comandos), causada por una asignación simple (el tiempo de ejecución aumenta de 0.8 ~ 0.9 segundos a 29.x segundos).Enorme disminución del rendimiento al acceder al objeto en matriz PHP asociativa

La secuencia de comandos primero obtiene una gran cantidad de datos de una base de datos MySQL y crea objetos de diferentes clases personalizadas. Después de esta búsqueda (php ahora usa alrededor de 500 MB de RAM), recorro una matriz de aproximadamente 3'500 Sample objetos, cada uno de los cuales tiene una matriz asociativa (tamaño alrededor de 100 entradas) como una de sus propiedades. Esta matriz contiene objetos Value, que son objetos pequeños con dos propiedades, y las claves son enteros menores que 6'000. Aquí es donde me encontré con el problema, consulte este código:

foreach ($samples as $id => $s) { # $s is now a 'Sample' object 
    $values = $s->values();   # $values is an array of 'Value' objects 

    if (isset($values[$match_id])) { 
     $num_tested++; 
     # $val = $values[$match_id];  # contains a 'Value' object 
     # $val = &$values[...]; -> the loop never ends (!) 
    } 
} 

Tenga en cuenta que la línea comentada. Si ejecuto el código tal como aparece aquí, este bloque se ejecuta durante aproximadamente 0,8 a 0,9 segundos. Si descomiento esta única línea, el bloque se ejecuta para casi 30 segundos. Descubrí que si la matriz no es asociativa (solo contiene claves consecutivas de 0 a aproximadamente 100), el tiempo de ejecución solo aumenta a 1.8 ~ 1.9 segundos.
Parece que esto sucede debido a las teclas de matriz no consecutivas que uso, pero de nuevo ¿por qué el rendimiento no se reduce llamando al isset($values[$match_id])? ¿Hay alguna solución para esto o tengo que vivir con eso?

Ejecutar PHP 5.3.0, Zend Engine v2.3.0, Mac OS X Server 10.6.2

+2

¿Puede darnos un 'print_r ($ values); die;'? –

+0

Hice un 'var_dump ($ values)', pero como una propiedad de un objeto 'Value' es otro objeto que a su vez tiene una matriz de otros objetos, el volcado es mucho más largo que mis 10'000 líneas de Command Line Buffer . – Pascal

+0

En otras palabras, los objetos 'Valor' no son objetos pequeños, ¿pero en realidad son la parte superior de los gráficos de objetos grandes? –

Respuesta

3

Si está ejecutando 5.3, mira en las nuevas estructuras de datos SPL. Ellos pueden producen un impulso de rendimiento significativo para colecciones más grandes, como se muestra here y here. Aparte de eso, es un poco difícil saber qué podría estar causando el problema. ¿Has intentado utilizar xdebug o Zend_Debugger para obtener más detalles?

+0

No, no estoy familiarizado con 'xdebug' o con Zend Debugger. Verificando las estructuras de datos Spl ... – Pascal

+0

xdebug y Zend_Debugger le permiten perfilar su aplicación. Le pueden dar un análisis detallado de los métodos que se llaman, la frecuencia y el tiempo que tardan en ejecutarse. xdebug es gratis, entonces ¿por qué no echarle un vistazo? – Gordon

1

Intente reemplazar $val = $values[$match_id] (asignación por copia) con $val =& $values[$match_id] (asignación por referencia) y vea si funciona mejor.

+0

Los objetos en PHP siempre se asignan por referencia.Sin embargo, este sería un excelente consejo si cada $ val no fuera un objeto. –

+0

No lo he intentado desde - como Lucas menciona - los objetos siempre son asignados por ref. Lo interesante de esto es: ** El ciclo no termina ** (al menos no lo hizo después de 10 minutos, cuando lo maté) ... – Pascal

Cuestiones relacionadas