Optimiza la velocidad de iteración

Informar un problema Ver fuente

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 interactivas.

  • 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 apagará después de un tiempo de inactividad a fin de 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 acciones, o bien puede enviarlas para la 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 en la 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 queda disponible en el árbol de resultados.

Ejecuta Bazel de forma iterativa

En un flujo de trabajo típico de un desarrollador, es común compilar (o ejecutar) un fragmento de código de manera 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, volvemos a analizar el estado del entorno de ejecución de Bazel:

La caché de análisis es un dato fundamental. Se puede dedicar una cantidad significativa de tiempo solo a las fases de carga y análisis de una ejecución en frío (es decir, una ejecución justo después de iniciar el servidor de Bazel o cuando se descartó la caché de análisis). En el caso de una única compilación en frío exitosa (p.ej., para una versión de producción), este costo es soportable, pero para compilar repetidamente el mismo destino es importante que se amortice este costo y no se repita en cada invocación.

La caché de análisis es bastante volátil. En primer lugar, es parte del estado en proceso del servidor de Bazel, por lo que perder el servidor 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 grafo de compilación (p.ej., debido a 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 servidores de Bazel y, de hecho, entre 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. Cualquiera de estas opciones se debe evitar durante el uso iterativo:

  • Ten cuidado de cambiar las marcas bazel en medio de un flujo de trabajo iterativo. Por ejemplo, combinar un bazel build -c opt con un bazel 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, se pierde la caché de análisis. El servidor de Bazel tiene un tiempo de inactividad configurable y, luego, se apaga. Puedes configurar este tiempo a través del archivo de bazelrc para satisfacer tus necesidades. El servidor también se reinició cuando cambian 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 cierra si presionas Ctrl-C varias veces mientras se ejecuta Bazel. Resulta tentador intentar ahorrar tiempo interrumpiendo una compilación en ejecución que ya no se necesita, pero solo presionar Ctrl + C una vez para solicitar un final ordenado de la invocación actual.

  • Si deseas usar varios conjuntos de marcas del mismo lugar 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 convertir esta condición en un error en lugar de una advertencia, puedes usar la marca --noallow_analysis_cache_discard (presentada en Bazel 6.4.0).