En esta página, se describe cómo optimizar el rendimiento de compilación de Bazel cuando se ejecuta Bazel de forma repetida.
Estado del entorno de ejecución de Bazel
Una invocación de Bazel implica varias partes que interactúan.
La interfaz de línea de comandos (CLI) de
bazel
es la herramienta de frontend para el usuario y recibe comandos del usuario.La herramienta de la CLI inicia un servidor de Bazel para cada base de salida distinta. Por lo general, el servidor de Bazel es persistente, pero se cerrará después de un tiempo de inactividad para no desperdiciar recursos.
El servidor de Bazel realiza los pasos de carga y análisis de un comando determinado (
build
,run
,cquery
, etc.), en el que construye las partes necesarias del gráfico de compilación en la memoria. Las estructuras de datos resultantes se retienen en el servidor de Bazel como parte de la caché de análisis.El servidor de Bazel también puede realizar la ejecución de la acción o enviar acciones para su ejecución remota si está configurado para hacerlo. Los resultados de las ejecuciones de acciones también se almacenan en caché, es decir, en la caché de acciones (o caché de ejecución, que puede ser local o remota, y se puede compartir entre servidores de Bazel).
El resultado de la invocación de Bazel está disponible en el árbol de salida.
Ejecuta Bazel de forma iterativa
En un flujo de trabajo típico de desarrollador, es común compilar (o ejecutar) un fragmento de código de forma repetida, a menudo con una frecuencia muy alta (p.ej., para resolver algún error de compilación o investigar una prueba fallida). En esta situación, es importante que las invocaciones repetidas de bazel
tengan la menor sobrecarga posible en relación con la acción subyacente y repetida (p.ej., invocar un compilador o ejecutar una prueba).
Con esto en mente, volvamos a observar el estado del entorno de ejecución de Bazel:
La caché de análisis es un dato fundamental. Se puede invertir una cantidad significativa de tiempo solo en las fases de carga y análisis de una ejecución en frío (es decir, una ejecución justo después de que se inició el servidor de Bazel o cuando se descartó la caché de análisis). Para una sola compilación en frío exitosa (p.ej., para una versión de producción), este costo es tolerable, pero para compilar el mismo destino de forma reiterada, es importante que este costo se amortize y no se repita en cada invocación.
La caché de análisis es bastante volátil. En primer lugar, forma parte del estado en proceso del servidor Bazel, por lo que, si se pierde el servidor, también se pierde la caché. Sin embargo, la caché también se invalida con mucha facilidad: por ejemplo, muchas marcas de línea de comandos bazel
hacen que se descarte la caché. Esto se debe a que muchas marcas afectan el gráfico de compilación (p.ej., debido a los atributos configurables). Algunos cambios de marca también pueden hacer que se reinicie el servidor de Bazel (p.ej., cambiar las opciones de inicio).
Una buena caché de ejecución también es valiosa para el rendimiento de la compilación. Una caché de ejecución se puede mantener de forma local en el disco o de forma remota. La caché se puede compartir entre los servidores de Bazel y, de hecho, entre los desarrolladores.
Evita descartar la caché de análisis
Bazel imprimirá una advertencia si se descartó la caché de análisis o se reinició el servidor. Debes evitar cualquiera de los siguientes casos durante el uso iterativo:
Ten en cuenta que debes cambiar las marcas
bazel
en medio de un flujo de trabajo iterativo. Por ejemplo, mezclar unbazel build -c opt
con unbazel cquery
hace que cada comando descarte la caché de análisis del otro. En general, intenta usar un conjunto fijo de marcas durante un flujo de trabajo en particular.Si se pierde el servidor de Bazel, también se pierde la caché de análisis. El servidor de Bazel tiene un tiempo de inactividad configurable, después del cual se apaga. Puedes configurar este tiempo a través de tu archivo bazelrc para satisfacer tus necesidades. El servidor también se reinició cuando cambiaron las marcas de inicio, por lo que, una vez más, evita cambiar esas marcas si es posible.
Ten en cuenta que el servidor de Bazel se finalizará si presionas Ctrl + C de forma reiterada mientras se ejecuta Bazel. Es tentador intentar ahorrar tiempo interrumpiendo una compilación en ejecución que ya no se necesita, pero solo presiona Ctrl + C una vez para solicitar un cierre elegante de la invocación actual.
Si deseas usar varios conjuntos de marcas del mismo lugar de trabajo, puedes usar varias bases de salida distintas, con la marca
--output_base
. Cada base de salida recibe su propio servidor de Bazel.