Si lo hace Python u otros lenguajes de socio pequeño, para el generador no debe ser desconocido. Sin embargo, muchos desarrolladores de PHP, probablemente no lo saben generador de funciones, posiblemente debido a que el generador no se introdujo en PHP 5.5.0, que también puede ser efecto generador no es muy obvio. Sin embargo, la función de generador es muy útil.
La explicación oficial:
Builder proporciona una manera más fácil de implementar un simple objetos iteración , clase definida comparación que implementa el iterador medios de interfaz, la complejidad y la sobrecarga de rendimiento se reduce considerablemente.
Builder le forEach escribir código bloque de código para recorrer un conjunto de datos sin la necesidad de crear una matriz en la memoria, que hará que su memoria alcanza el límite superior, o va a ocupar un considerable tiempo de procesamiento. En su lugar, se puede escribir una función de generador, al igual que una costumbre regular de la función como una función normal sólo de retorno una vez que la diferencia es que el generador puede ser necesario de rendimiento en muchas ocasiones, con el fin de generar la iteración valor deseado.
ventaja
Después de escuchar que hablar directamente con el concepto de estimación o confuso, por lo que vamos a hablar de las ventajas que puede ser capaz de despertar su interés. ¿Cuáles son las ventajas de que el generador, de la siguiente manera:
- generador de rendimiento de las aplicaciones PHP tendrá un impacto muy grande
- Ahorrar una gran cantidad de memoria de PHP se ejecuta código
- Más adecuado para gran cantidad de datos calculado
Por lo tanto, estas características fantásticas exactamente cómo hacerlo? Tomemos un ejemplo.
La introducción del concepto de
En primer lugar, poner el concepto generador de carga, vistazo a una función de PHP simple:
function createRange($number){
$data = [];
for($i=0;$i<$number;$i++){
$data[] = time();
}
return $data;
}
Esta es una función de PHP muy comunes, a menudo usan el tiempo para hacer frente a algunos de la matriz. El código aquí es muy simple:
- Creamos una función.
- Dentro de la función contiene un
for
bucle, que el ciclo en el momento actual$data
en el interior for
Ciclo ha terminado, el$data
cabo de retorno.
A continuación siempre, seguimos. Escribimos una función, esta función devuelve el valor del bucle de imprimir:
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
sleep(1);//这里停顿1秒,我们后续有用
echo $value.'<br />';
}
Miramos dentro de los resultados de carreras del navegador:
Aquí es perfecto, sin ningún problema. (Por supuesto, sleep(1)
el efecto no se puede ver)
Pensando en un problema
Observamos que en la llamada de función createRange
tiempo para $number
pasar valor es 10, un número muy pequeño. Supongamos que ahora pasa un valor 10000000
(10 millones).
Luego, en la función createRange
dentro del for
bucle que necesitaría para ejecutar 1000
millón de veces. Y hay 1000
diez mil valor se colocó $data
en el interior, y el $data
conjunto se coloca en la memoria. Por lo tanto, cuando se llama a la función cuando se llevará una gran cantidad de memoria.
En este caso, el generador puede florecer.
Crear un constructor
Modificamos el código directamente, se observa:
function createRange($number){
for($i=0;$i<$number;$i++){
yield time();
}
}
Y al igual que el aspecto de este código, hemos eliminado la matriz $data
, y no devuelve nada, pero time()
antes de usar una palabra claveyield
El uso de generadores
corremos el segundo párrafo del código:
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
sleep(1);
echo $value.'<br />';
}
Nos encontramos milagrosamente, y el valor de salida de las veces sin el uso de generadores no es lo mismo. Aquí el valor (sello de tiempo) de un intervalo de un segundo.
Aquí es en realidad intervalos de un segundo sleep(1)
consecuencias. Pero ¿por qué no lo hizo el primer intervalo de tiempo? Esto se debe a:
- Generador cuando no esté en uso:
createRange
la función delfor
ciclo, el resultado se coloca de forma rápida$data
, y vuelve inmediatamente. Por lo tanto,foreach
el ciclo es una matriz fija. - Cuando se utiliza el generador:
createRange
el valor no es generar rápidamente una sola vez, sino que dependeforeach
del ciclo.foreach
tiempo de ciclo,for
tiempo de ejecución.
Aquí, debe ser una pequeña pista en el generador.
Profundidad generador de conocimiento
análisis de código
Analicemos de código justo.
function createRange($number){
for($i=0;$i<$number;$i++){
yield time();
}
}
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
sleep(1);
echo $value.'<br />';
}
Vamos a restaurar la ejecución de código.
- En primer lugar llamar a la
createRange
función, el paso de parámetros10
, pero elfor
valor se ejecuta una vez y luego se detuvo, y dijoforeach
el primer ciclo puede ser un valor. foreach
Comenzó a$result
ciclo, lo primerosleep(1)
, y luego comenzófor
a llevar a cabo un valor de salida.foreach
La preparación de un segundo ciclo, antes del inicio del segundo ciclo, que esfor
el ciclo luego preguntó de nuevo.for
Por lo tanto, realiza un bucle, tell fecha y hora generadosforeach
.foreach
Obtener el segundo valor, y salidas. Debido aforeach
lasleep(1)
, por lo quefor
el retardo cíclico de un segundo para generar la hora actual
Por lo tanto, toda la ejecución del código, siempre que un valor récord involucrados en el ciclo, la memoria es sólo una pieza de información.
Ya sea que comenzó a propagación de $number
la cantidad, ya que no todos generan conjuntos de resultados de inmediato, por lo que la memoria es siempre el valor de un ciclo.
comprensión conceptual
Aquí, usted debe probablemente ya entender lo que un generador. Debajo de nosotros, la próxima generación Principio.
En primer lugar, un concepto claro: Constructor de palabras clave de rendimiento no es el valor de retorno, la jerga se denomina valor de salida, simplemente generar un valor
A continuación, el código en foreach
lo que está circulando? De hecho, cuando se utiliza un generador de PHP, devuelve una Generator
clase de objeto. foreach
Puede ser el objeto de iteraciones, cada iteración, PHP pasará Generator
el valor calculado siguiente ejemplo requiere iteración. Por lo foreach
que necesitamos saber el valor de la siguiente iteración.
Por otra parte, en la operación de for
que se ejecuta el bucle, se detendrá inmediatamente. Esperar a que foreach
la próxima vez que el ciclo una y otra vez for
cuando el próximo piden un valor, el for
bucle se llevará a cabo una vez más, a continuación, parada de nuevo inmediatamente. no se ejecuta hasta que la condición no se cumple final.
La aplicación de desarrollo real
Muchos desarrolladores de PHP no entienden el generador, se trata principalmente de aplicaciones sin darse cuenta. Por lo tanto, lo que ha generado la aplicación en el desarrollo real?
Leer archivos de gran tamaño
los desarrolladores de PHP a menudo tienen que leer los archivos de gran tamaño, tales como archivo CSV, archivo de texto, o algunos archivos de registro. Si estos archivos de gran tamaño, tales como 5 G. Entonces, en un momento, todo el contenido se lee en la memoria de cálculo no es realista.
Aquí generador puede ser útil. Si no, mire un ejemplo: leer archivos de texto
Creamos un texto documento de texto, y entramos en unas pocas líneas de texto, la demostración leer.
<?php
header("content-type:text/html;charset=utf-8");
function readTxt()
{
# code...
$handle = fopen("./test.txt", 'rb');
while (feof($handle)===false) {
# code...
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
# code...
echo $value.'<br />';
}
El gráfico de salida de los resultados podemos ver el código completamente normal.
Sin embargo, el código detrás de la aplicación de las reglas no era en absoluto lo mismo. Use el generador lee el archivo, la primera línea de la primera lectura, la segunda lectura de la segunda fila, y así sucesivamente, cada vez que se carga en la memoria sólo la línea de texto , reduce en gran medida la memoria utilizar.
Por lo tanto, incluso si el G leer el texto, no se preocupe, puede escribir código como la lectura de archivos pequeños de la misma.