test-zig-cc/README.md
Motiejus Jakštys 255db31ad2 % -> times
2022-12-20 13:07:37 +02:00

136 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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][1] and [llvm14][2]. 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][3], 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.
[1]: https://sr.ht/~motiejus/bazel-zig-cc
[2]: https://github.com/grailbio/bazel-toolchain
[3]: https://github.com/bazelbuild/bazel/issues/16138