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 que interactúan.

  • La interfaz de línea de comandos (CLI) de bazel es la herramienta de frontend del usuario y recibe comandos del usuario.

  • La herramienta de la CLI inicia un servidor de Bazel para cada base de salida distinta. El servidor de Bazel suele ser persistente, pero se apagará 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 retienen en el servidor de Bazel como parte de la caché del 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é, es decir, en la caché de acciones (o caché de ejecución, que puede ser local o remota, y puede compartirse entre los servidores de Bazel).

  • El resultado de la invocación de Bazel está 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 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 repetida subyacente (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 que se inició el servidor de Bazel o cuando se descartó la caché de análisis). En el caso de una sola compilación en frío exitosa (p.ej., para una versión de producción), este costo es soportable, pero, si compilas el mismo objetivo de forma repetida, es importante que se amortice 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 hace que se pierda 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 en las marcas 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 guardar de forma local en el disco o de forma remota. La caché se puede compartir entre servidores de Bazel y, por cierto, 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. Se debe evitar cualquiera de los siguientes casos durante el uso iterativo:

  • Ten en cuenta cambiar las marcas bazel en medio de un flujo de trabajo iterativo. Por ejemplo, si mezclas un bazel build -c opt con un bazel cquery, cada comando descarta la caché de análisis del otro. En general, intenta usar un conjunto fijo de marcas durante un flujo de trabajo específico.

  • 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 cierra. Puedes configurar esta hora a través del archivo Bazelrc para que se adapte a tus necesidades. El servidor también se reinició cuando cambian las marcas de inicio, por lo que, si es posible, evita cambiarlas.

  • Ten en cuenta que se cerrará el servidor de Bazel 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 presiona Ctrl + C una vez para solicitar un final correcto 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.