Производительность сборки Gradle vs Bazel - PullRequest
4 голосов
/ 02 ноября 2019

Итак, все сейчас говорят о bazel, но миграция на него не автоматизирована (gradle лучше в этом отношении при переходе с maven). Поэтому я не хочу тратить время на ручное преобразование любого репозитория в него.

Но я не могу найти никакой информации о разнице в скорости сборки между последними версиями gradle (5.6>) и bazel (1.0).

Может кто-нибудь поделиться ссылкой или собственным опытом? В основном меня интересуют инкрементные сборки, в которых изменилась только пара файлов.

Ответы [ 2 ]

5 голосов
/ 02 ноября 2019

Dropbox недавно провел несколько тестов :

enter image description here

Обратите внимание, что чистая сборка без сценария кэширования значительно замедляется для Bazelтогда как сценарий инкрементной сборки значительно быстрее.

Узлы сборки Bazel, как правило, имеют меньшую степень детализации, чем у Gradle. Распространено видеть цели java_library только с одним исходным файлом. Действия командной строки в этих единицах сборки, также известные как цели, индивидуально кэшируются (локально или удаленно) и объединяются для создания java_binary.

Со многими небольшими сборочными единицами обычно требуется выполнить больше действий и, следовательно, больше дискового ввода-вывода и вычислений, что приводит к более медленному начальному, чистому времени сборки.

Некоторые исполняемые файлы этих действий могут также иметь высокую стоимость запуска (например, javac), которая складывается при многократном перезапуске этих процессов. В Bazel есть механизм, называемый постоянными работниками, в котором исполняемый процесс для отдельных действий (например, оболочка компилятора для javac, tsc, scalac или ghc) может сохраняться при выполнении действий, экономя время запуска и обеспечиваяеще более низкий уровень кэширования на уровне процесса.

С другой стороны, небольшие блоки сборки Bazel позволяют выполнять очень инкрементные сборки и быструю итеративную разработку, как показано на диаграмме выше.

Небольшие блоки сборки также позволяют Bazel формировать граф зависимостей с высокой степенью параллелизма. При удаленном выполнении вы можете параллельно выполнять 100 и 1000 небольших действий по сборке.

График зависимостей также сильно оптимизирован для случая сборки без операции. Если в вашем проекте ничего не изменилось, Bazel должно потребоваться как можно меньше времени, чтобы выяснить, что ничего не изменилось, поэтому ничего не нужно делать.

Недостаток медленной чистой сборки также можно устранить с помощью удаленных кэшей. удаленное выполнение или не запускание относительно редкого bazel clean, поскольку сборки стремятся быть герметичными, детерминированными и согласованными . Сборка со 100% -ным удаленным попаданием в кеш - обычное явление для Bazel.

0 голосов
/ 04 ноября 2019

Хорошо, я перенес проект с закрытым исходным кодом, содержащий ~ 100_000 loc java, на bazel.

Gradle 5.6.3 vs bazel 1.0.1

Я не мог измерить чистую сборку, потому что я не уверен, как отделить шаг загрузки зависимостей от шага компиляции, и я все равно не беспокоюсь об этом сценарии использования. Как я уже сказал, мой интерес связан с производительностью разработчиков, а следовательно, и с инкрементными сборками.

Я использовал следующее в BUILD для Bazel, поэтому я не использовал наиболее детализированный подход, потому что я не думаю, что это действительноремонтопригоден, и это может использовать любой, кроме крупных компаний с большим количеством разработчиков. И в любом случае я вижу тот факт, что мне нужно сделать это вручную, чтобы повысить скорость сборки, как недостаток Bazel.

java_binary(
    srcs = glob(["src/main/java/**/*.java"]),
    resources = glob(["src/main/resources/**"]),
    ...
)

Инкрементная сборка с одним или двумя измененными файлами.

gradle - 1s , bazel - 4.227s

Я пробовал это несколько раз, и каждый раз gradle был значительно быстрее. Я не тестировал инкрементную сборку, когда было изменено более одного или двух файлов, возможно, в этом сценарии bazel будет таким же или быстрее, чем gradle.

Нет операционной сборки gradle - 700 мс , bazel - 0,090 мс

Таким образом, скорость работы грейдера, похоже, является победителем для производительности разработчиков. У Bazel есть более безопасные значения по умолчанию (склонность к ошибкам включена по умолчанию) в gradle, вы должны включить его самостоятельно, но ИМХО гибкость gradle перевешивает более безопасные значения по умолчанию bazel.

...