En esta página, se describe cómo optimizar el rendimiento de compilación de Bazel cuando se ejecuta Bazel de forma repetida.
Estado de tiempo de ejecución de Bazel
Una invocación de Bazel involucra varias partes que interactúan entre sí.
La interfaz de línea de comandos (CLI) de
bazel
es la herramienta de frontend orientada al usuario y recibe comandos del usuario.La herramienta de CLI inicia un servidor de Bazel para cada base de salida distinta. Por lo general, el servidor de Bazel es persistente, pero se apaga después de un tiempo de inactividad para no desperdiciar recursos.
El servidor de Bazel realiza los pasos de carga y análisis para 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 conservan 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 puede enviar acciones para la ejecución remota si está configurado para hacerlo. Los resultados de las ejecuciones de acciones también se almacenan en caché, específicamente en la caché de acciones (o caché de ejecución, que puede ser local o remota, y se puede compartir entre los servidores de Bazel).
El resultado de la invocación de Bazel está disponible en el árbol de salida.
Cómo ejecutar 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 repetida (p.ej., invocar un compilador o ejecutar una prueba).
Con esto en mente, volvamos a observar el estado 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 repetidamente el mismo destino, es importante que este costo se amortice 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 de Bazel, por lo que perder el servidor implica perder la caché. Sin embargo, la caché también se invalida con mucha facilidad: por ejemplo, muchas marcas de línea de comandos de 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 atributos configurables). Algunos cambios en las marcas también pueden provocar 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 si se reinició el servidor. Cualquiera de estas opciones se debe evitar durante el uso iterativo:
Ten en cuenta que no debes cambiar las marcas
bazel
en medio de un flujo de trabajo iterativo. Por ejemplo, si se mezcla unbazel build -c opt
con unbazel cquery
, cada comando descarta la caché de análisis del otro. En general, intenta usar un conjunto fijo de marcas durante la duración de un flujo de trabajo en particular.Si se pierde el servidor de Bazel, 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 que se adapte a tus necesidades. El servidor también se reinicia cuando cambian las marcas de inicio, por lo que, nuevamente, evita cambiar esas marcas si es posible.
Ten en cuenta que el servidor de Bazel se detiene si presionas Ctrl+C varias veces mientras se ejecuta Bazel. Es tentador intentar ahorrar tiempo interrumpiendo una compilación en ejecución que ya no es necesaria, pero solo presiona Ctrl+C una vez para solicitar un final correcto de la invocación actual.
Si quieres usar varios conjuntos de marcas del mismo espacio de trabajo, puedes usar varias bases de salida distintas, que se cambian con la marca
--output_base
. Cada base de salida obtiene su propio servidor de Bazel.
Para que esta condición sea un error en lugar de una advertencia, puedes usar la marca --noallow_analysis_cache_discard
(introducida en Bazel 6.4.0).