blob: eaf7655b813aba4700c9fcd9787d13552c762654 [file] [log] [blame] [view]
## Git hook
On a new checkout, run this to install the formatting check hook:
```
$ ln -s ../../git-pre-commit .git/hooks/pre-commit
```
## Path handling and Unicode safety
See the longer discussion of Unicode in general in the
[design notes](design_notes.md).
Concretely, we currently use Rust `String` for all paths and file contents, but
internally interpret them as as bytes (not UTF-8) including using `unsafe`
sometimes to convert.
Based on my superficial understanding of how safety relates to UTF-8 in Rust
strings, it's probably harmless given that we never treat strings as Unicode,
but it's also possible some code outside of our control relies on this. But it
does mean there's a bunch of kind of needless `unsafe`s in the code, and some of
them are possibly actually doing something bad.
We could fix this by switching to using a bag of bytes type, like
https://crates.io/crates/bstr. But it is pretty invasive. We would need to use
that not only for paths but also console output, error messages, etc. And it's
not clear (again, see above design notes discussion) that using bags of bytes is
the desired end state, so it's probably not worth doing.
## Profiling
### gperftools
I played with a few profilers, but I think the gperftools profiler turned out to
be significantly better than the others. To install:
```
$ apt install libgoogle-perftools-dev
$ go install github.com/google/pprof@latest
```
To use:
```
[possibly modify main.rs to make the app do more work than normal]
$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libprofiler.so CPUPROFILE=p ./target/release/n2 ...
$ pprof -http=:8080 ./target/release/n2 p
```
The web server it brings up shows an interactive graph, top functions, annotated
code, disassembly...
### Mac
```
$ cargo instruments --release --template time --bin n2 -- -C ~/projects/llvm-project-16.0.0.src/build clang-format
```
TODO: notes on this vs `cargo flamegraph`.
### Windows
It appears `perf` profiling of Rust under WSL2 is not a thing(?).
## Benchmarking
### Simple
This benchmarks end-to-end n2 load time, by asking to build a nonexistent target:
1. `cargo install hyperfine`
2. `$ hyperfine -i -- './target/release/n2 -C ~/llvm-project/llvm/utils/gn/out/ xxx'`
### Micro
There are microbenchmarks in the `benches/` directory. Run them with:
```
$ cargo bench
```
If there is a `build.ninja` in the `benches/` directory, the parsing benchmark
will load it. For example, you can copy the `build.ninja` generated by the
LLVM CMake build system (66mb on my system!).
To run just the parsing benchmark:
```
$ cargo bench --bench parse -- parse
```
When iterating on benchmarks, it can help build time to disable `lto` in release
mode by commenting out the `lto =` line in `Cargo.toml`. (On my system, `lto`
is worth ~13% of parsing performance.)