DataDog / datadog-static-analyzer

Datadog Static Analyzer
https://docs.datadoghq.com/static_analysis/
Apache License 2.0
100 stars 12 forks source link

[STAL-2515] Introduce `release-dev` cargo profile #455

Closed jasonforal closed 3 months ago

jasonforal commented 3 months ago

TL;DR increase developer iteration speed (incremental compilation time reduced by 95%+)

What problem are you trying to solve?

It is currently common to use cargo build --release when developing the analyzer because the runtime performance of an optimized build is ~3x faster, making it optimal for testing the analyzer against large repos (it makes the difference between a 3 minute monorepo scan and a 10 minute one).

However, when using --release, when a single line changes, the binaries need to be rebuilt, and that takes over 2 minutes (on a very fast M1 Macbook), significantly reducing the ability to iterate quickly.

The reason for this is that we currently use lto = true for release mode (which is important for actual releases, but not development).

To illustrate, here is a trace of a --release compilation where all crates have been compiled and then 1 single line of code in analyze.rs is changed:

release

As you can see, 1m56s are spent in the linker, (despite only 1 second of actual codegen).

What is your solution?

Introduce a release-dev Cargo profile, which is inherited from --release mode, but turns off lto and includes standard functionality from --debug (symbols, assertions, etc.)

This has numerous benefits

Effect

Whereas before, an incremental --release build took 2m1s, an incremental release-dev build takes around 2s:

release-dev

Methodology

  1. Build the datadog-static-analyzer binary completely from scratch.
    
    ❯ cargo build --release --bin datadog-static-analyzer
    Finished `release` profile [optimized + debuginfo] target(s) in 2m 30s

❯ cargo build --profile release-dev --bin datadog-static-analyzer Finished release-dev profile [optimized + debuginfo] target(s) in 1m 07s


2. Change a single line of code:
```rust
// crates/static-analysis-kernel/src/analysis/analyze.rs
// ...
let cache_bust = 1; // (number changed to trigger recompilation)
  1. Re-run cargo build with timing information
❯ RUSTC_BOOTSTRAP=1 cargo rustc --profile release --bin datadog-static-analyzer -- -Z self-profile
Finished `release` profile [optimized + debuginfo] target(s) in 2m 01s

❯ RUSTC_BOOTSTRAP=1 cargo rustc --profile release-dev --bin datadog-static-analyzer -- -Z self-profile
Finished `release-dev` profile [optimized + debuginfo] target(s) in 2.60s

Alternatives considered

What the reviewer should know