Red de conocimiento informático - Aprendizaje de programación - ¿Cuánto aumenta la velocidad de php ob_start?

¿Cuánto aumenta la velocidad de php ob_start?

Dado que PHP es un lenguaje de scripting que "compila y ejecuta al mismo tiempo", también proporciona una forma muy conveniente de utilizar el almacenamiento en caché del conjunto de resultados: incluyendo dinámicamente el segmento de código de definición de datos correspondiente.

Recientemente he estado optimizando el rendimiento del programa por un tiempo y tengo una idea interesante que me gustaría compartir con ustedes.

La caché es un modo de aplicación típico de la estrategia "espacio por tiempo" y un método importante para mejorar el rendimiento del sistema. El uso de caché puede reducir en gran medida la cantidad de operaciones de la base de datos en el caso de grandes volúmenes de acceso, reducir significativamente la carga del sistema y mejorar el rendimiento del sistema. En comparación con el almacenamiento en caché de páginas, el conjunto de resultados es una especie de "datos sin procesar" que no contiene información de formato. La cantidad de datos es relativamente pequeña y se puede formatear nuevamente, por lo que es bastante flexible. Dado que PHP es un lenguaje de secuencias de comandos que "compila y ejecuta al mismo tiempo", también proporciona una forma muy conveniente de utilizar el almacenamiento en caché del conjunto de resultados hasta cierto punto: utilizar el caché incluyendo dinámicamente el segmento de código de definición de datos correspondiente. Si se construye un caché en "RamDisk", la eficiencia debería mejorarse aún más. A continuación se muestra un pequeño código de muestra como referencia.

// cargar datos con caché

función

load_data($id,$cache_lifetime) {

// los datos devueltos

$data =

array();

// crear nombre de archivo de caché

$cache_filename =

' cache_'.$id.'.php';

// comprobar la hora de la última modificación del archivo caché

$cache_filetime = filemtime($cache_filename); (time() -

$cache_filetime <= $cache_lifetime) {

//** el caché no caduca

include($cache_filename) <; /p>

} else {

//** el caché está

caducado

// cargar datos desde la base de datos

// ...

mientras

($dbo->nextRecord()) {

// $datos[] = ...

}

// formatear

los datos como un archivo php

$data_cache = "

mientras (lista ($clave, $val) =

cada($datos)) {

$data_cache .= "\$datos['$clave']=array('" ;

$data_cache .= "'NOMBRE'=>\"".qoute($val['NOMBRE'])."\","

$data_cache .= " 'VALOR '=>\"".qoute($val['VALUE'])."\""

$data_cache .= ";);\r\n";

}

$data_cache = "?>\r\n";

// guarda los datos en el archivo de caché

if ($fd =

fopen($cache_filename,'w+')) {

fputs($fd,$data_cache

fclose($fd); p>}

}

return $data;

} > Situaciones aplicables:

1. Los datos son relativamente estables, principalmente. operaciones de lectura.

2. Las operaciones con archivos son más rápidas que las operaciones con bases de datos.

3. Acceso a datos complejos, acceso a grandes volúmenes de datos, acceso intensivo a datos, la carga de la base de datos del sistema es extremadamente pesada.

4. Estructura de separación Web/DB o estructura de base de datos única multi-Web.

Problemas no confirmados:

1. ¿La lectura y escritura de archivos durante el acceso simultáneo causarán problemas de bloqueo?

2. ¿Cuál es el rendimiento cuando hay demasiados archivos de datos involucrados?

Ideas ampliadas:

1. Generar código de definición de datos JavaScript y llamarlo en el cliente.

2. No lo he pensado todavía...

Espero discutirlo juntos.

Almacenamiento en caché

Si desea que su enorme aplicación PHP tenga un mejor rendimiento, usar el almacenamiento en caché también es un buen método. Hay muchas soluciones de almacenamiento en caché disponibles, incluidas: Zend

Cache, APC y Afterburner Cache.

Todos estos productos son "módulos de almacenamiento en caché". Cuando se produce por primera vez una solicitud de un archivo .php, guardan el código intermedio PHP en la memoria del servidor web y luego responden a solicitudes posteriores con la versión "compilada". Este enfoque realmente puede mejorar el rendimiento de la aplicación porque reduce el acceso al disco al mínimo (el código ha sido leído y analizado) y el código se ejecuta directamente en la memoria, lo que hace que el servidor responda a las solicitudes mucho más rápido. Por supuesto, el módulo de almacenamiento en caché también monitoreará los cambios en los archivos fuente PHP y volverá a almacenar en caché la página si es necesario, evitando así que el usuario reciba páginas que todavía se generan con código PHP obsoleto. Debido a que los módulos de almacenamiento en caché pueden reducir significativamente la carga en el servidor y mejorar la eficiencia de respuesta de las aplicaciones PHP, son muy adecuados para sitios web con cargas pesadas.

Cómo elegir estos productos de almacenamiento en caché

Zend Cache es el software comercial de Zend Technologies, y Zend

Technologies es el mencionado anteriormente que nos proporciona la Motor PHP y empresa gratuita Zend Optimizer. Zend

¡El caché es realmente bien merecido! Para páginas PHP grandes, puede sentir que la velocidad aumentará después de la primera ejecución y el servidor tendrá más recursos disponibles. Desafortunadamente, este producto no es gratuito, pero en algunos casos aún puede ser una ganga.

Afterburner Cache es un módulo de almacenamiento en caché gratuito de Bware Technologies. Este producto se encuentra actualmente en versión Beta. Afterburner

Cache se parece a Zend Cache, pero su mejora de rendimiento no es (todavía) comparable a la de Zend Cache, y no se puede utilizar con Zend

Optimizer Work.

APC es la abreviatura de Alternative PHP Cache, que es otro módulo de almacenamiento en caché gratuito de Community

Connect. El producto ya es lo suficientemente estable para uso formal y parece mejorar en gran medida la velocidad de respuesta a las solicitudes.

Acerca de la compresión

El módulo gratuito de Apache mod_gzip de Comunicaciones remotas

Tiene la capacidad de comprimir contenido web estático para navegadores que admiten este tipo de codificación de contenido. Para la gran mayoría de contenido web estático, mod_gzip funciona muy bien. mod_gzip se puede compilar fácilmente en Apache y también se puede utilizar como DSO. Según la empresa de comunicaciones Remote

, mod_gzip también puede comprimir contenido dinámico de mod_php, mod_perl, etc. Lo intenté una y otra vez, pero no pareció funcionar. He leído muchos foros y artículos sobre mod_gzip y parece que se espera que este problema se resuelva en la próxima versión de mod_gzip (probablemente 1.3.14.6f). Hasta entonces, podemos usar mod_gzip en las partes estáticas del sitio web.

Sin embargo, a veces realmente queremos comprimir contenido dinámico, por lo que debemos buscar otras formas. Una forma es usar class.gzip_encode.php, que es una clase PHP que se puede usar para comprimir el contenido de la página llamando a ciertas funciones de la clase al principio y al final del script PHP. Si desea implementar esta solución a nivel de sitio web, puede llamar a estas funciones desde las directivas auto_prepend y auto_append en el archivo php.ini. Aunque este método es eficaz, sin duda genera más gastos generales para los sitios web con mucha carga.

Para obtener instrucciones detalladas sobre cómo utilizar esta clase, consulte su código fuente. La descripción de su código fuente es bastante completa y el autor te cuenta todo lo que necesitas saber.

PHP

4.0.4 tiene un nuevo controlador de caché de salida ob_gzhandler, que es similar a la clase anterior, pero su uso es diferente. Cuando utilice ob_gzhandler, agregue lo siguiente a php.ini:

output_handler = ob_gzhandler

Esta línea de código hace que PHP active el almacenamiento en caché de salida y comprima todo lo que envía. Si por alguna razón no desea agregar esta línea de código a php.ini, también puede cambiar el comportamiento predeterminado del servidor (sin compresión) a través del archivo .htaccess en el directorio donde se encuentra el archivo fuente de PHP, con el siguiente sintaxis:

php_value

output_handler ob_gzhandler

O llamado desde código PHP, como se muestra a continuación:

ob_start("ob_gzhandler") ;

El método de utilizar identificadores de caché de salida es realmente muy efectivo y no supone ninguna carga especial para el servidor. Sin embargo, debe tenerse en cuenta que Netscape

Communicator tiene un soporte deficiente para gráficos comprimidos, por lo que, a menos que pueda asegurarse de que todos los usuarios utilicen el navegador IE, debe desactivar los gráficos JPEG y GIF comprimidos. En general, esta compresión funciona para todos los demás archivos, pero se recomienda probarla por separado para cada navegador, especialmente si utiliza complementos o visores de datos especiales. Esto es especialmente importante.

Consejo de lectura: el paquete de almacenamiento en búfer de PEAR proporciona un marco para almacenar en búfer contenido dinámico, consultas de bases de datos y llamadas a funciones PHP. Este artículo presenta cómo usar PEAR para almacenar en búfer programas PHP

Usar PEAR para almacenar en búfer programas PHP

El almacenamiento en búfer es un tema candente en el mundo de PHP, porque las páginas dinámicas generadas por PHP serán almacenado en caché cada vez que el usuario lo solicita. Todo debe recalcularse, independientemente de si el resultado de la solicitud es el mismo. Al mismo tiempo, PHP

compilará el script cada vez. Sin duda, una sobrecarga así sería insoportable para un sitio web con mucho tráfico. Afortunadamente, los resultados de la Web se pueden almacenar en caché sin necesidad de volver a ejecutar y compilar el script. Los productos comerciales como ZendCache o el caché PHP alternativo de código abierto brindan la capacidad de compilar scripts PHP en código de bytes y método de almacenamiento en búfer. El paquete de almacenamiento en búfer de

PEAR

proporciona un marco para almacenar en búfer contenido dinámico, consultas de bases de datos y llamadas a funciones PHP.

Al igual que Perl tiene CPAN y TeX tiene CTAN, PHP

también tiene su propia biblioteca de recursos central para almacenar clases, bibliotecas y módulos. Esta biblioteca se llama PEAR (Extensión y complemento PHP

Repositorio).

Este artículo asume que ha instalado el entorno PEAR. De lo contrario, puede descargarlo desde el sitio web de PHP. El paquete de buffer de PEAR

contiene una clase de buffer general y varias subclases especializadas. Las clases de búfer utilizan clases de contenedor para almacenar y administrar datos almacenados en búfer.

El siguiente es el contenedor que contiene actualmente el

búfer PEAR, así como sus respectivos parámetros:

archivo: el contenedor de archivos almacena los datos almacenados en el búfer. en el sistema de archivos. es el contenedor más rápido.

cache_dir

--Este es el directorio donde el contenedor almacena los archivos.

filename_prefix: el prefijo del archivo de caché, por ejemplo: "cache_".

shm -- shm

El contenedor coloca los datos almacenados en el buffer en la memoria compartida. Las pruebas comparativas muestran que, bajo la implementación actual, este contenedor es más lento que el contenedor de archivos.

shm_key --

***El valor clave utilizado por la memoria compartida.

shm_perm: utiliza permisos *** para compartir segmentos de datos de memoria.

shm_size --

El tamaño de la memoria compartida asignada.

sem_key: el valor clave del semáforo.

sem_perm -- Permisos para semáforos.

db --

capa de abstracción de la base de datos de PEAR.

dsn: el DSN de la conexión de la base de datos. Puede consultar la documentación de la base de datos de PEAR.

cache_table --

El nombre de la tabla.

phplib -- phplib

El contenedor utiliza la capa de abstracción de la base de datos para almacenar buffers.

db_class

db_file

db_path

archivo_local

ruta_local

ext/dbx

-- Extensión de la capa de abstracción de la base de datos de PHP

. Si desea almacenar buffers en la base de datos, puede usar este contenedor.

módulo

host

db

nombre de usuario

contraseña

cache_table

persistente

La mejora de rendimiento obtenida al usar PEAR Cache depende del contenedor de búfer que elija. Por ejemplo, almacenar los resultados de la base de datos en el caché de la base de datos nuevamente no parece tener sentido.

El módulo de búfer de funciones de PEAR Cache

puede almacenar en búfer los resultados de cualquier función o método, ya sea la función incorporada de PHP

o el usuario. Función definida. De forma predeterminada, se utiliza un contenedor de archivos para colocar los datos almacenados en el búfer en un directorio llamado function_cache.

Cache_Function

El constructor de la clase puede tener tres parámetros opcionales:

$container: el nombre del contenedor del buffer.

$container_options

: Parámetros de matriz del contenedor del buffer.

$expires: el tiempo (en segundos) en que caduca el objeto del búfer.

Cuando una llamada de función normal utiliza el método

call() de la clase Cache_Function, se puede activar el almacenamiento en búfer. Llamar a call()

es fácil, un parámetro es el nombre de la función, luego los parámetros de la función, el segundo parámetro es el primero en la función que se llamará, y así sucesivamente, veamos en el ejemplo:

Ejemplo 1

Llamada de funciones y métodos del búfer

// Llama al búfer de función de PEAR Cache.

require_once

'Cache/Function.php';

// Definir algunas clases y funciones.

clase foo {

función

bar($prueba) {

echo

"foo:: bar($test)

";

}

}

clase barra {

función

p>

foobar($objeto) {

echo

'$'.$objeto.'->foobar('.$objeto.')

';

}

}

$bar =

nueva barra;

función foobar() {

echo 'foobar()';

}

//

Obtener el objeto Cache_Function

$cache = new Cache_Function();

// Almacena en caché la función estática bar() de la clase foo

(foo::bar()).

$cache->call('foo::bar',

'test');

// $bar->foobar()

p>

$cache->call('bar->foobar',

'bar');

$cache->call('foobar '); >

A continuación usamos

Cache_Output para almacenar en búfer la salida:

Ejemplo 2 Almacenamiento en búfer de la salida del script

/ / Cargando PEAR

Búfer de salida de caché

require_once 'Cache/Output.php';

$cache = new

Cache_Output(' file', array( 'cache_dir' => '.') );

//

Calcule la etiqueta de la página que se almacenará en el búfer, asumimos que el almacenamiento en búfer de la página depende de

// URL, variables HTTP GET y POST y

cookies.

$cache_id = $cache->generateID(

array('url' =>

$REQUEST_URI, '

publicación' => $HTTP_POST_VARS, 'cookies' =>

$HTTP_COOKIE_VARS) );

// Almacenamiento en búfer de consultas

if ($content =

$cache->start($cache_id)) {

// Golpe de búfer

echo

$content;

die ();

}

// Pérdida de búfer

// -- Inserte el código de generación de contenido aquí

--

// Almacena la página en el caché

echo $cache->end();

Usando la clase Cache_Output, es fácil crear una base de datos dinámica. sitio web impulsado La aplicación se convierte en estática, lo que mejora en gran medida el rendimiento del sitio. Cada vez más sitios utilizan GZIP para comprimir

contenido HTML, lo que reduce el consumo de ancho de banda del servidor y también puede beneficiar mucho a los usuarios que utilizan Modem para acceder a Internet.

Cache_OutputCompression

Extiende las funciones de la clase Cache_Output. Almacena en buffer el contenido HTML comprimido con GZIP, ahorrando así tiempo de compresión de la CPU.

Consejos de lectura: en este artículo, presentaremos brevemente el análisis de aplicaciones PHP, cómo cambiar el código del script y compararemos varios valores de parámetros antes y después de la optimización.

Optimización del rendimiento de aplicaciones PHP

El mayor beneficio de programar en PHP es lo fácil que es aprender este lenguaje de programación y sus ricas bibliotecas. Incluso sin saber mucho sobre las funciones que necesitamos utilizar, podemos adivinar cómo realizar una tarea específica.

Aunque PHP es muy simple y fácil de aprender, todavía necesitamos dedicar un poco de tiempo para aprender algunas habilidades de programación de PHP, especialmente aquellas relacionadas con el rendimiento y el uso de la memoria. En PHP existen muchos trucos que nos permiten reducir el uso de memoria y mejorar el rendimiento de las aplicaciones. En este artículo, presentaremos brevemente el análisis de aplicaciones PHP, cómo cambiar el código del script y compararemos varios valores de parámetros antes y después de la optimización.

Al configurar procedimientos de sincronización en el programa y ejecutar estos códigos repetidamente, podemos obtener un conjunto de datos sobre la velocidad de ejecución del programa. Estos datos se pueden utilizar para descubrir cuellos de botella en el programa y cómo optimizarlos. it, mejora el rendimiento de la aplicación.

Quizás los lectores hayan oído hablar de la biblioteca PEAR. Usaremos la biblioteca PEAR para crear ejemplos que necesitamos usar durante el análisis. Esta es también la forma más fácil de analizar el código existente. Nos permite analizar el código sin utilizar productos comerciales.

El nombre de la biblioteca que vamos a utilizar es PEAR::Benchmark, la cual es muy útil para analizar y probar el rendimiento del código. Esta biblioteca proporciona una clase llamada Benchmark_Timer(), que puede registrar el tiempo entre una llamada a función y la siguiente llamada a función.

Al probar el rendimiento del código, podemos obtener un resultado detallado de la ejecución del script, que es muy simple, de la siguiente manera:

include_once("Benchmark/Timer.php");

$bench

= new Benchmark_Timer;

$bench-> start();

$bench->

setMarker( 'Iniciar del guión');

//

Ahora en estado de sueño durante unos minutos

sleep(5);

$ bench-> stop();

//

Obtener información de análisis del temporizador

print_r($bench->

getProfiling ()); >

La salida después de ejecutar el código anterior es la siguiente:

Array

(

[0] = > Matriz

(

[nombre] =>

Inicio

[hora] => 1013214253.05751200

[diff] =>

-

[total] => 0

)

[1] =>

Array

(

[nombre] => Inicio del script

[hora] =>

1013214253.05761100

[diff] => 9.8943710327148E-05

[total]

=> 9.8943710327148E-05

)

[2] =>

Matriz

(

[nombre] => Detener

[hora] =>

1013214258.04920700

[diff] => 4.9915959835052

[total] =>

4.9916949272156

)

)

Los números anteriores pueden parecer un conjunto inconexo de números, pero si el tamaño del programa es mayor, estos números pueden ser muy útiles.

Quizás los lectores también puedan adivinar que la primera entrada de la matriz es el método real para llamar a la clase Benchmark_Timer(), como

$bench->

start(), $bench-> setMarker() y $bench->

stop(), los números asociados con estas entradas son bastante simples, ahora estudiemos estos números en detalle:

[0] => Matriz

(

[nombre] => Inicio

[hora] => 1013214253.05751200

[diff] => -

[total] => 0

)

La entrada de tiempo se refiere a cuándo iniciar el método Benchmark_Timer() () llama al Marca de tiempo UNIX La entrada diff indica el intervalo de tiempo entre esta llamada y la última llamada. Dado que aquí no hay ninguna llamada anterior, se muestra un guión. La entrada total se refiere al tiempo desde el comienzo de la prueba hasta este tiempo. Cantidad de tiempo que se ejecutó el código antes de una llamada específica. Echemos un vistazo al resultado de la siguiente matriz:

[1]

=> Array

(

[nombre] = > Inicio del script

[hora] => 1013214253.05761100

[diff] =>

9.8943710327148E-05

[ total ] => 9.8943710327148E-05

)

De los números anteriores podemos ver que después de llamar a $bench->

start(), el programa Después de ejecutar durante 9.8943710327148E-05 segundos (es decir, 0.0000989 segundos), se llama a $bench->

setMarker(....).

Una experiencia de prueba de rendimiento de la vida real

Aunque el ejemplo anterior es bueno, realmente no lo es cuando se trata de decidir cómo optimizar el diseño del código de su sitio. A continuación, utilizaré mi propia experiencia personal como técnico de sitios web para ilustrar cómo resolver problemas de rendimiento.

Realmente no entiendo el código utilizado por el sitio web, porque se desarrolló durante muchos años en función de necesidades específicas: un módulo contiene el código de conversión del sitio web y otro módulo registra el uso del sitio web. Otros módulos también tienen sus propias funciones. El desarrollador principal del sitio web y yo nos dimos cuenta de que era necesario optimizar el código del sitio web, pero no sabíamos cuál era el problema.

Para completar la tarea lo más rápido posible, comencé a estudiar el código del script principal del sitio web y agregué algunos comandos $bench->

setMarker() a todos los scripts. codes y sus archivos incluidos, y luego analizó la salida de $bench->

getProfiling() y me sorprendieron los resultados. Resultó que el problema radicaba en una llamada de función relacionada con el código de conversión. Para obtener un nombre de idioma específico (como en para inglés), esta función se usa cientos de veces en cada página. Cada vez que se llama a esta función, el código del script consulta una base de datos MySQL para obtener el nombre real del idioma de una tabla de base de datos.

Así que creamos un sistema de almacenamiento en búfer para este tipo de información. Después de solo 2 días de trabajo, mejoramos enormemente el rendimiento del sistema y la cantidad de páginas vistas aumentó en un 40% en la primera semana. Por supuesto, este es sólo un ejemplo de cómo el análisis de código puede mejorar el rendimiento de una aplicación de Internet o un sitio web de Internet.

Llamada a la función de prueba de rendimiento

Aunque Benchmark_Timer() es particularmente útil cuando se analiza un script o una página web (y los archivos que lo contienen), no es científico porque es necesario obtener la Los datos analizados tenemos que cargar el script varias veces y no se llama contra una clase o función.

Otra clase en la biblioteca PEAR::Benchmark llamada Benchmark_Iterator puede resolver bien este problema. Puede mostrar información de análisis para funciones o métodos de clase específicos. Su propósito es poder obtener resultados consistentes de las pruebas porque sabemos que si ejecutamos un script una vez y se ejecuta durante 10 segundos, eso no significa que siempre se ejecutará durante 10 segundos cada vez.

En

de cualquier modo, veamos algunos ejemplos:

//

Código para conectar con la base de datos

include_once("DB.php");

$dsn = array(

'phptype'

=> 'mysql',

'hostspec' => 'localhost',

'base de datos'

=> 'nombre_base_datos',

'nombre de usuario' =>

'nombre_usuario',

'contraseña' => 'contraseña'

);

$dbh =

DB :: conectar($dsn);

función getCreatedDate($id)

{

global

$dbh;

> $stmt = "SELECCIONE fecha_creación DE los usuarios DONDE

id=$id";

// Utilice PEAR::DB aquí

$ fecha_creada = $dbh->

getOne($stmt);

if ((PEAR::isError($created_date)) ||

(empty( $ fecha_creada))) {

return false;

} else

{

return $created_date;

}

}

include_once

'Benchmark/Iterate.php';

$bench = nuevo Benchmark_Iterate;

//

Ejecute la función getDate 10 veces

$bench-> run(10, 'getCreatedDate', 1);

//

Imprimir información de análisis

print_r($bench-> get()); > Ejecutar el código anterior puede producir resultados similares a los siguientes:

Array

p>

(

[1] => 0.055413007736206

[2] =>

0.0012860298156738

[3] = > 0.0010279417037964

[4] =>

0.00093603134155273

[5] => 0.00094103813171387

[6] =>

0.00092899799346924

[7] => 0.0010659694671631

[8] =>

0.00096404552459717

[9] => 0.0010690689086914

[10] =>

0.00093603134155273

[media] => 0.0064568161964417

[iter

aciones]

=> 10

)

Los números anteriores son fáciles de entender. La entrada media representa el tiempo promedio de 10 ejecuciones de getCreatedDate(). función. En las pruebas reales, deberías ejecutarlo al menos 1000 veces, pero los resultados de este ejemplo son suficientes para ilustrar el problema.