Compare commits
3
Commits
ce4a1a127d
...
0f8493eb02
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f8493eb02 | ||
|
|
f8d3bb5b2b | ||
|
|
0a74fe3143 |
+28
-24
@@ -9,8 +9,9 @@ cargo build --release
|
||||
```
|
||||
|
||||
Plain cargo. No wrapper, no memory ceiling, no reduced optimisation.
|
||||
A clean release build peaks at **1.92 GB** and takes **2m17s** on a
|
||||
4-core / 7.6 GB VM.
|
||||
A clean release build peaks at **~2.0 GB** and takes **1m46s** on a
|
||||
4-core / 7.6 GB VM; an incremental rebuild after touching one file is a
|
||||
few seconds.
|
||||
|
||||
If that's not what you're seeing, read on.
|
||||
|
||||
@@ -87,35 +88,38 @@ Nothing there reduces the optimisation of shipped code.
|
||||
|
||||
---
|
||||
|
||||
## Known remaining inefficiency
|
||||
## Project layout
|
||||
|
||||
`src/main.rs` re-declares the whole module tree (`mod app; mod config;
|
||||
...`) instead of depending on the `keydr` lib target, so **every module
|
||||
compiles twice** — once for the lib, once for the bin. The `i18n!` macro
|
||||
must therefore be invoked in both crate roots (`t!()` expands to
|
||||
`crate::_rust_i18n_t`, so it must exist in each crate).
|
||||
All application code lives in the **library** (`src/lib.rs` → `src/run.rs`
|
||||
and the module tree). `src/main.rs` is a 10-line entry point that calls
|
||||
`keydr::run()`.
|
||||
|
||||
Measured with `cargo build --release --timings` on a clean tree, the two
|
||||
duplicated units are the slowest in the whole graph:
|
||||
This matters for build time. `main.rs` used to re-declare the whole module
|
||||
tree (`mod app; mod config; ...`), which made the binary a *second
|
||||
independent crate*: every module — and the entire rust-i18n translation
|
||||
table — was compiled twice, and 281 unit tests ran twice.
|
||||
|
||||
Measured effect of consolidating it, clean release build:
|
||||
|
||||
```
|
||||
33.7s keydr (bin)
|
||||
26.0s keydr (lib)
|
||||
1.4s generate_test_profiles (bin)
|
||||
------
|
||||
61.0s of 292.2s total unit-seconds (21%)
|
||||
before after
|
||||
keydr (bin) 33.7s 0.3s
|
||||
keydr (lib) 26.0s 31.0s
|
||||
keydr total 61.0s 32.4s (-28.6s)
|
||||
total unit-seconds 292.2s 264.5s
|
||||
wall clock 2m14s 1m46s (-28s, -21%)
|
||||
```
|
||||
|
||||
So restructuring `main.rs` to `use keydr::...` would save roughly 26s of
|
||||
compile work — real, but nowhere near half the build. Wall-clock saving is
|
||||
smaller still, since those units partly overlap with dependency
|
||||
compilation across 3 parallel jobs (292s of unit-work compressed into
|
||||
~2m15s wall). Worth doing for code hygiene; not a build-performance
|
||||
emergency.
|
||||
Test coverage is unchanged — 341 unique tests before and after. The
|
||||
execution count dropping from 622 to 340 is the duplicate run disappearing.
|
||||
|
||||
Note the remaining ~79% is dependency compilation (`reqwest` 12.7s,
|
||||
`clap_builder` 11.4s, `toml_edit` 9.3s, `tokio` 8.0s...), which is
|
||||
one-time work that incremental builds skip entirely.
|
||||
**Keep it this way:** if you add a module, declare it in `src/lib.rs`, not
|
||||
`src/main.rs`. Re-declaring modules in the binary would silently restore
|
||||
the double compile.
|
||||
|
||||
The remaining ~79% of build time is dependency compilation (`reqwest`
|
||||
12.7s, `clap_builder` 11.4s, `toml_edit` 9.3s, `tokio` 8.0s...), which
|
||||
incremental builds skip entirely.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+9
-7
@@ -1,12 +1,12 @@
|
||||
// Library target exists solely for criterion benchmarks.
|
||||
// The binary entry point is main.rs; this file re-declares the module tree so
|
||||
// that bench harnesses can import types via `keydr::engine::*` / `keydr::session::*`.
|
||||
// Most code is only exercised through the binary, so suppress dead_code warnings.
|
||||
#![allow(dead_code)]
|
||||
//! keydr — terminal typing tutor with adaptive learning.
|
||||
//!
|
||||
//! All application code lives here, including the TUI event loop (`run`).
|
||||
//! `src/main.rs` is a thin wrapper so nothing is compiled twice; see
|
||||
//! docs/BUILDING.md. New modules belong in this file, not in main.rs.
|
||||
|
||||
rust_i18n::i18n!("locales", fallback = "en");
|
||||
|
||||
// Public: used by benchmarks and the generate_test_profiles binary
|
||||
// Public: used by the binary, benchmarks, and generate_test_profiles.
|
||||
pub mod config;
|
||||
pub mod engine;
|
||||
pub mod keyboard;
|
||||
@@ -14,9 +14,11 @@ pub mod l10n;
|
||||
pub mod session;
|
||||
pub mod store;
|
||||
|
||||
// Private: required transitively by engine/session (won't compile without them)
|
||||
mod app;
|
||||
mod event;
|
||||
mod generator;
|
||||
mod i18n;
|
||||
mod run;
|
||||
mod ui;
|
||||
|
||||
pub use run::run;
|
||||
|
||||
+2
-7531
File diff suppressed because it is too large
Load Diff
+7850
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user