testing of github.com/uber/hermetic_cc_toolchain
Go to file
2023-04-17 14:29:54 +03:00
bin let it be so 2022-10-19 12:00:28 +03:00
results update results with more test data 2022-12-20 12:42:19 +02:00
.bazelrc specify bazel version + more tests 2022-12-20 11:32:17 +02:00
.bazelversion use a newer zig and newer bazel-zig-cc 2023-04-17 14:29:54 +03:00
.build.yml build: add warmup step 2022-11-21 07:06:49 +02:00
.envrc update README, remove buildifier 2022-11-21 06:25:58 +02:00
.gitignore let it be so 2022-10-19 12:00:28 +03:00
BUILD update README, remove buildifier 2022-11-21 06:25:58 +02:00
LICENSE add license 2022-11-21 06:41:34 +02:00
main.cc add forgotten main.cc 2022-11-21 06:19:32 +02:00
README.md % -> times 2022-12-20 13:07:37 +02:00
WORKSPACE use a newer zig and newer bazel-zig-cc 2023-04-17 14:29:54 +03:00

bazel-zig-cc and llvm

bazel-zig-cc has a performance issue when compiling many files. This repository reproduces that.

The test

Compiles 64 small binaries with bazel-zig-cc and llvm14. The tests were run on an x86_64 8-core machine running Ubuntu 22.04.

TLDR

Extracting the fastest meaningful benchmarks in all categories (from the section below):

                              'bazel build                                                                             --experimental_reuse_sandbox_directories //...' ran
2.77 ± 0.08 times faster than 'bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --experimental_reuse_sandbox_directories //...'
2.85 ± 0.07 times faster than 'bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28              --experimental_reuse_sandbox_directories //...'

This demonstrates that adding a hermetic toolchain to a project caused 2.77x slowdown on this project. Note that we are not counting llvm_toolchain//... as a real toolchain -- one needs a sysroot to compile anything meaningful anyway (which zig bundles with the compiler).

Once we have determined that a hermetic C++ toolchain is required, bazel-zig-cc is about 2.8% slower than its contender plain llvm14.

Results

Benchmark 1: bazel build  --spawn_strategy=local //...
  Time (mean ± σ):      4.813 s ±  0.140 s    [User: 0.015 s, System: 0.009 s]
  Range (min … max):    4.529 s …  5.007 s    10 runs
 
Benchmark 2: bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux --spawn_strategy=local //...
  Time (mean ± σ):      6.921 s ±  0.238 s    [User: 0.013 s, System: 0.011 s]
  Range (min … max):    6.513 s …  7.279 s    10 runs
 
Benchmark 3: bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --spawn_strategy=local //...
  Time (mean ± σ):      9.336 s ±  0.347 s    [User: 0.013 s, System: 0.012 s]
  Range (min … max):    8.968 s … 10.220 s    10 runs
 
Benchmark 4: bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 --spawn_strategy=local //...
  Time (mean ± σ):      9.311 s ±  0.190 s    [User: 0.014 s, System: 0.010 s]
  Range (min … max):    9.050 s …  9.667 s    10 runs
 
Benchmark 5: bazel build  --experimental_reuse_sandbox_directories //...
  Time (mean ± σ):      4.726 s ±  0.051 s    [User: 0.011 s, System: 0.011 s]
  Range (min … max):    4.653 s …  4.793 s    10 runs
 
Benchmark 6: bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux --experimental_reuse_sandbox_directories //...
  Time (mean ± σ):      7.674 s ±  0.370 s    [User: 0.012 s, System: 0.012 s]
  Range (min … max):    7.000 s …  8.492 s    10 runs
 
Benchmark 7: bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --experimental_reuse_sandbox_directories //...
  Time (mean ± σ):     13.098 s ±  0.329 s    [User: 0.018 s, System: 0.006 s]
  Range (min … max):   12.365 s … 13.510 s    10 runs
 
Benchmark 8: bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 --experimental_reuse_sandbox_directories //...
  Time (mean ± σ):     13.465 s ±  0.292 s    [User: 0.014 s, System: 0.012 s]
  Range (min … max):   13.033 s … 13.897 s    10 runs
 
Benchmark 9: bazel build  --spawn_strategy=sandboxed //...
  Time (mean ± σ):      4.766 s ±  0.179 s    [User: 0.014 s, System: 0.008 s]
  Range (min … max):    4.553 s …  5.224 s    10 runs
 
Benchmark 10: bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux --spawn_strategy=sandboxed //...
  Time (mean ± σ):      8.666 s ±  0.116 s    [User: 0.014 s, System: 0.009 s]
  Range (min … max):    8.504 s …  8.883 s    10 runs
 
Benchmark 11: bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --spawn_strategy=sandboxed //...
  Time (mean ± σ):     33.827 s ±  0.630 s    [User: 0.019 s, System: 0.010 s]
  Range (min … max):   32.121 s … 34.412 s    10 runs
 
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet PC without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
 
Benchmark 12: bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 --spawn_strategy=sandboxed //...
  Time (mean ± σ):     20.396 s ±  0.330 s    [User: 0.016 s, System: 0.011 s]
  Range (min … max):   19.966 s … 20.939 s    10 runs
 
Summary
                                  'bazel build                                                                             --experimental_reuse_sandbox_directories //...' ran
    1.01 ± 0.04 times faster than 'bazel build                                                                             --spawn_strategy=sandboxed               //...'
    1.02 ± 0.03 times faster than 'bazel build                                                                             --spawn_strategy=local                   //...'
    1.46 ± 0.05 times faster than 'bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux              --spawn_strategy=local                   //...'
    1.62 ± 0.08 times faster than 'bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux              --experimental_reuse_sandbox_directories //...'
    1.83 ± 0.03 times faster than 'bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux              --spawn_strategy=sandboxed               //...'
    1.97 ± 0.05 times faster than 'bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28              --spawn_strategy=local                   //...'
    1.98 ± 0.08 times faster than 'bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --spawn_strategy=local                   //...'
    2.77 ± 0.08 times faster than 'bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --experimental_reuse_sandbox_directories //...'
    2.85 ± 0.07 times faster than 'bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28              --experimental_reuse_sandbox_directories //...'
    4.32 ± 0.08 times faster than 'bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28              --spawn_strategy=sandboxed               //...'
    7.16 ± 0.15 times faster than 'bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --spawn_strategy=sandboxed               //...'
Command Mean [s] Min [s] Max [s] Relative
bazel build --experimental_reuse_sandbox_directories //... 4.726 ± 0.051 4.653 4.793 1.00
bazel build --spawn_strategy=sandboxed //... 4.766 ± 0.179 4.553 5.224 1.01 ± 0.04
bazel build --spawn_strategy=local //... 4.813 ± 0.140 4.529 5.007 1.02 ± 0.03
bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux --spawn_strategy=local //... 6.921 ± 0.238 6.513 7.279 1.46 ± 0.05
bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux --experimental_reuse_sandbox_directories //... 7.674 ± 0.370 7.000 8.492 1.62 ± 0.08
bazel build --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux --spawn_strategy=sandboxed //... 8.666 ± 0.116 8.504 8.883 1.83 ± 0.03
bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 --spawn_strategy=local //... 9.311 ± 0.190 9.050 9.667 1.97 ± 0.05
bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --spawn_strategy=local //... 9.336 ± 0.347 8.968 10.220 1.98 ± 0.08
bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --experimental_reuse_sandbox_directories //... 13.098 ± 0.329 12.365 13.510 2.77 ± 0.08
bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 --experimental_reuse_sandbox_directories //... 13.465 ± 0.292 13.033 13.897 2.85 ± 0.07
bazel build --platforms=@zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 --spawn_strategy=sandboxed //... 20.396 ± 0.330 19.966 20.939 4.32 ± 0.08
bazel build --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux --spawn_strategy=sandboxed //... 33.827 ± 0.630 32.121 34.412 7.16 ± 0.15

Explanation:

  • --spawn_strategy=local is the baseline. This is the theoretically fastest approach (no sandbox), but unfit for production.
  • --spawn_strategy=sandboxed is the default for Bazel. This is what happens if one does not pass any arguments.
  • --experimental_reuse_sandbox_directories is an optimization which is meaningful on sandboxes with many files. As of Bazel 6 this has been promoted to stable, so safe to use and, as one can see in the numbers, recommended with both bazel-zig-cc and a nontrivial sysroot. As a result, this is the most important benchmark to look at.

Flame graphs and discussion

Flame graphs in results/. Only of historical interest, because the biggest performance issues have been resolved with a combination of zig and bazel-zig-cc changes.