agy-superpowers 5.2.2 → 5.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -150
- package/package.json +1 -1
- package/template/agent/rules/CLAUDE.md +80 -0
- package/template/agent/rules/code-styles.md +31 -32
- package/template/agent/rules/debug-confirmation-policy.md +2 -0
- package/template/agent/rules/file-length-policy.md +2 -0
- package/template/agent/rules/git-policy.md +7 -0
- package/template/agent/rules/language-matching.md +2 -0
- package/template/agent/rules/scratch-scripts.md +39 -0
- package/template/agent/rules/superpowers.md +8 -51
- package/template/agent/skills/executing-plans/SKILL.md +17 -0
- package/template/agent/skills/systematic-debugging/SKILL.md +16 -0
- package/template/agent/skills/test-driven-development/SKILL.md +16 -0
- package/template/agent/skills/verification-before-completion/SKILL.md +22 -0
- package/template/agent/skills/writing-plans/SKILL.md +16 -0
- package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
- package/template/agent/skills/analytics-setup/SKILL.md +0 -51
- package/template/agent/skills/api-design/SKILL.md +0 -193
- package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
- package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
- package/template/agent/skills/backend-developer/SKILL.md +0 -148
- package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
- package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
- package/template/agent/skills/community-manager/SKILL.md +0 -115
- package/template/agent/skills/content-marketer/SKILL.md +0 -111
- package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
- package/template/agent/skills/cto-architect/SKILL.md +0 -133
- package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
- package/template/agent/skills/data-analyst/SKILL.md +0 -147
- package/template/agent/skills/devops-engineer/SKILL.md +0 -117
- package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
- package/template/agent/skills/game-design/SKILL.md +0 -194
- package/template/agent/skills/game-developer/SKILL.md +0 -175
- package/template/agent/skills/growth-hacker/SKILL.md +0 -122
- package/template/agent/skills/idea-validator/SKILL.md +0 -55
- package/template/agent/skills/indie-legal/SKILL.md +0 -53
- package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
- package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
- package/template/agent/skills/launch-strategist/SKILL.md +0 -62
- package/template/agent/skills/market-researcher/SKILL.md +0 -53
- package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
- package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
- package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
- package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
- package/template/agent/skills/real-time-features/SKILL.md +0 -194
- package/template/agent/skills/retention-specialist/SKILL.md +0 -123
- package/template/agent/skills/rust-developer/SKILL.md +0 -281
- package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
- package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
- package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
- package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
- package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
- package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
- package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
- package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
- package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
- package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
- package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
- package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
- package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
- package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
- package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
- package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
- package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
- package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
- package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
- package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
- package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
- package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
- package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
- package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
- package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
- package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
- package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
- package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
- package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
- package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
- package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
- package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
- package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
- package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
- package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
- package/template/agent/skills/saas-architect/SKILL.md +0 -139
- package/template/agent/skills/security-engineer/SKILL.md +0 -133
- package/template/agent/skills/seo-specialist/SKILL.md +0 -130
- package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# opt-codegen-units
|
|
2
|
-
|
|
3
|
-
> Set `codegen-units = 1` for maximum optimization in release builds
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
By default, Cargo splits code into multiple codegen units for parallel compilation. This speeds up builds but prevents some cross-unit optimizations. Setting `codegen-units = 1` allows LLVM to optimize across the entire crate, potentially improving runtime performance by 5-20% at the cost of slower builds.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```toml
|
|
12
|
-
# Cargo.toml - default settings
|
|
13
|
-
[profile.release]
|
|
14
|
-
# codegen-units defaults to 16
|
|
15
|
-
# Fast to compile, but misses optimization opportunities
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Good
|
|
19
|
-
|
|
20
|
-
```toml
|
|
21
|
-
# Cargo.toml - optimized for runtime performance
|
|
22
|
-
[profile.release]
|
|
23
|
-
codegen-units = 1 # Single unit = better optimization
|
|
24
|
-
lto = true # Link-time optimization
|
|
25
|
-
opt-level = 3 # Maximum optimization
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## What codegen-units Affects
|
|
29
|
-
|
|
30
|
-
| Codegen Units | Compile Time | Runtime Performance | Memory Use |
|
|
31
|
-
|---------------|--------------|---------------------|------------|
|
|
32
|
-
| 16 (default) | Faster | Baseline | Lower |
|
|
33
|
-
| 4-8 | Moderate | Slightly better | Moderate |
|
|
34
|
-
| 1 | Slower | Best | Higher |
|
|
35
|
-
|
|
36
|
-
## How It Works
|
|
37
|
-
|
|
38
|
-
```rust
|
|
39
|
-
// With codegen-units = 16:
|
|
40
|
-
// - Crate split into 16 independent compilation units
|
|
41
|
-
// - Compiled in parallel
|
|
42
|
-
// - Limited visibility between units for optimization
|
|
43
|
-
|
|
44
|
-
// With codegen-units = 1:
|
|
45
|
-
// - Entire crate in single unit
|
|
46
|
-
// - LLVM sees all code at once
|
|
47
|
-
// - Can inline across module boundaries
|
|
48
|
-
// - Better dead code elimination
|
|
49
|
-
// - Better constant propagation
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Full Release Profile
|
|
53
|
-
|
|
54
|
-
```toml
|
|
55
|
-
[profile.release]
|
|
56
|
-
# Maximum runtime performance
|
|
57
|
-
opt-level = 3
|
|
58
|
-
lto = "fat"
|
|
59
|
-
codegen-units = 1
|
|
60
|
-
panic = "abort" # Smaller binary, slight perf gain
|
|
61
|
-
strip = true # Smaller binary
|
|
62
|
-
|
|
63
|
-
[profile.release-with-debug]
|
|
64
|
-
# Performance with debugging ability
|
|
65
|
-
inherits = "release"
|
|
66
|
-
debug = true # Keep debug symbols
|
|
67
|
-
strip = false
|
|
68
|
-
|
|
69
|
-
[profile.bench]
|
|
70
|
-
# For benchmarking
|
|
71
|
-
inherits = "release"
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Build Time Trade-offs
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
# Default release build (fast compile)
|
|
78
|
-
cargo build --release
|
|
79
|
-
# Time: ~30s
|
|
80
|
-
|
|
81
|
-
# Optimized release build (slow compile, fast runtime)
|
|
82
|
-
# With codegen-units = 1, lto = "fat"
|
|
83
|
-
cargo build --release
|
|
84
|
-
# Time: ~2-5min, but potentially 10-20% faster binary
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Per-Profile Configuration
|
|
88
|
-
|
|
89
|
-
```toml
|
|
90
|
-
# Fast debug builds
|
|
91
|
-
[profile.dev]
|
|
92
|
-
codegen-units = 256 # Maximum parallelism
|
|
93
|
-
|
|
94
|
-
# Fast CI builds
|
|
95
|
-
[profile.ci]
|
|
96
|
-
inherits = "release"
|
|
97
|
-
codegen-units = 16 # Balance compile time vs runtime
|
|
98
|
-
lto = "thin" # Faster than "fat"
|
|
99
|
-
|
|
100
|
-
# Production release
|
|
101
|
-
[profile.production]
|
|
102
|
-
inherits = "release"
|
|
103
|
-
codegen-units = 1
|
|
104
|
-
lto = "fat"
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## When to Use What
|
|
108
|
-
|
|
109
|
-
```rust
|
|
110
|
-
// codegen-units = 16 (default)
|
|
111
|
-
// - Development builds
|
|
112
|
-
// - CI where compile time matters
|
|
113
|
-
// - When runtime performance isn't critical
|
|
114
|
-
|
|
115
|
-
// codegen-units = 1
|
|
116
|
-
// - Production deployments
|
|
117
|
-
// - Performance-critical applications
|
|
118
|
-
// - Final releases
|
|
119
|
-
// - Benchmarking
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Measuring Impact
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
# Build with different settings
|
|
126
|
-
cargo build --release
|
|
127
|
-
|
|
128
|
-
# Benchmark
|
|
129
|
-
cargo bench
|
|
130
|
-
|
|
131
|
-
# Compare binary sizes
|
|
132
|
-
ls -lh target/release/my_binary
|
|
133
|
-
|
|
134
|
-
# Profile runtime
|
|
135
|
-
perf stat ./target/release/my_binary
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## See Also
|
|
139
|
-
|
|
140
|
-
- [opt-lto-release](./opt-lto-release.md) - Link-time optimization
|
|
141
|
-
- [opt-pgo-profile](./opt-pgo-profile.md) - Profile-guided optimization
|
|
142
|
-
- [opt-target-cpu](./opt-target-cpu.md) - CPU-specific optimization
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# opt-cold-unlikely
|
|
2
|
-
|
|
3
|
-
> Mark unlikely code paths with `#[cold]` to help compiler optimization
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
The `#[cold]` attribute tells the compiler that a function is rarely called. The compiler uses this to optimize code layout—keeping cold code away from hot code improves instruction cache utilization. Combined with branch layout optimization, this can measurably improve performance.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// All branches treated equally
|
|
13
|
-
fn validate(input: &str) -> Result<Data, ValidationError> {
|
|
14
|
-
if input.is_empty() {
|
|
15
|
-
return Err(ValidationError::Empty); // Rare
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if input.len() > 1000 {
|
|
19
|
-
return Err(ValidationError::TooLong); // Rare
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if !input.is_ascii() {
|
|
23
|
-
return Err(ValidationError::NonAscii); // Rare
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// This is the common case
|
|
27
|
-
Ok(parse_data(input))
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Good
|
|
32
|
-
|
|
33
|
-
```rust
|
|
34
|
-
fn validate(input: &str) -> Result<Data, ValidationError> {
|
|
35
|
-
if input.is_empty() {
|
|
36
|
-
return cold_empty_error();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if input.len() > 1000 {
|
|
40
|
-
return cold_too_long_error();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if !input.is_ascii() {
|
|
44
|
-
return cold_non_ascii_error();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
Ok(parse_data(input))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
#[cold]
|
|
51
|
-
fn cold_empty_error() -> Result<Data, ValidationError> {
|
|
52
|
-
Err(ValidationError::Empty)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#[cold]
|
|
56
|
-
fn cold_too_long_error() -> Result<Data, ValidationError> {
|
|
57
|
-
Err(ValidationError::TooLong)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
#[cold]
|
|
61
|
-
fn cold_non_ascii_error() -> Result<Data, ValidationError> {
|
|
62
|
-
Err(ValidationError::NonAscii)
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## What #[cold] Does
|
|
67
|
-
|
|
68
|
-
1. **Code placement**: Cold functions are placed in separate code sections, away from hot code
|
|
69
|
-
2. **Branch prediction**: Compiler generates branch hints favoring the non-cold path
|
|
70
|
-
3. **Inlining decisions**: Cold functions are not inlined into hot paths
|
|
71
|
-
4. **Optimization budget**: Compiler spends less effort optimizing cold code
|
|
72
|
-
|
|
73
|
-
## Common Cold Patterns
|
|
74
|
-
|
|
75
|
-
```rust
|
|
76
|
-
// Error handling
|
|
77
|
-
#[cold]
|
|
78
|
-
fn handle_error<E: std::fmt::Display>(e: E) -> ! {
|
|
79
|
-
eprintln!("Fatal error: {}", e);
|
|
80
|
-
std::process::exit(1);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Logging rare events
|
|
84
|
-
#[cold]
|
|
85
|
-
fn log_rare_event(event: &Event) {
|
|
86
|
-
log::warn!("Rare event occurred: {:?}", event);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Fallback paths
|
|
90
|
-
#[cold]
|
|
91
|
-
fn slow_fallback(data: &Data) -> Output {
|
|
92
|
-
// This path should rarely be taken
|
|
93
|
-
compute_slowly(data)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Panic handlers
|
|
97
|
-
#[cold]
|
|
98
|
-
fn panic_invalid_state(state: &State) -> ! {
|
|
99
|
-
panic!("Invalid state: {:?}", state);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Assertions and Invariants
|
|
104
|
-
|
|
105
|
-
```rust
|
|
106
|
-
fn get_unchecked(&self, index: usize) -> &T {
|
|
107
|
-
if index >= self.len {
|
|
108
|
-
cold_bounds_panic(index, self.len);
|
|
109
|
-
}
|
|
110
|
-
unsafe { &*self.ptr.add(index) }
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
#[cold]
|
|
114
|
-
#[inline(never)]
|
|
115
|
-
fn cold_bounds_panic(index: usize, len: usize) -> ! {
|
|
116
|
-
panic!("index out of bounds: the len is {} but the index is {}", len, index);
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Combining with #[inline(never)]
|
|
121
|
-
|
|
122
|
-
```rust
|
|
123
|
-
// Usually combine both for maximum effect
|
|
124
|
-
#[cold]
|
|
125
|
-
#[inline(never)]
|
|
126
|
-
fn error_path() -> Error {
|
|
127
|
-
// Complex error construction stays out of hot code
|
|
128
|
-
Error {
|
|
129
|
-
backtrace: Backtrace::capture(),
|
|
130
|
-
context: gather_context(),
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Measuring Impact
|
|
136
|
-
|
|
137
|
-
```rust
|
|
138
|
-
// Check code layout with objdump
|
|
139
|
-
// objdump -d target/release/binary | less
|
|
140
|
-
|
|
141
|
-
// Look for .cold sections
|
|
142
|
-
// nm target/release/binary | grep cold
|
|
143
|
-
|
|
144
|
-
// Profile to verify improvement
|
|
145
|
-
// perf stat -e cache-misses,cache-references ./binary
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## See Also
|
|
149
|
-
|
|
150
|
-
- [opt-inline-never-cold](./opt-inline-never-cold.md) - Combining with inline(never)
|
|
151
|
-
- [opt-likely-hint](./opt-likely-hint.md) - Branch prediction hints
|
|
152
|
-
- [err-result-over-panic](./err-result-over-panic.md) - Error handling
|
package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# opt-inline-always-rare
|
|
2
|
-
|
|
3
|
-
> Use `#[inline(always)]` sparingly—only for critical hot paths proven by profiling
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
`#[inline(always)]` forces the compiler to inline a function regardless of heuristics. Overuse increases binary size, hurts instruction cache, and can slow down code. The compiler is usually smarter about inlining than humans. Reserve this for measured hot paths where benchmarks prove a benefit.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Annotating everything - trusting intuition over data
|
|
13
|
-
#[inline(always)]
|
|
14
|
-
pub fn get_name(&self) -> &str {
|
|
15
|
-
&self.name
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
#[inline(always)]
|
|
19
|
-
pub fn calculate_tax(amount: f64) -> f64 {
|
|
20
|
-
amount * 0.1
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
#[inline(always)]
|
|
24
|
-
fn helper(x: i32) -> i32 {
|
|
25
|
-
x + 1
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Result: bloated binary, poor cache utilization
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Good
|
|
32
|
-
|
|
33
|
-
```rust
|
|
34
|
-
// Let compiler decide for most functions
|
|
35
|
-
pub fn get_name(&self) -> &str {
|
|
36
|
-
&self.name
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
pub fn calculate_tax(amount: f64) -> f64 {
|
|
40
|
-
amount * 0.1
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Only force inline for proven hot paths
|
|
44
|
-
impl Hasher for MyHasher {
|
|
45
|
-
// Hasher::write is called millions of times in tight loops
|
|
46
|
-
// Profiling showed 15% improvement from forced inlining
|
|
47
|
-
#[inline(always)]
|
|
48
|
-
fn write(&mut self, bytes: &[u8]) {
|
|
49
|
-
// Very small, very hot
|
|
50
|
-
self.state = self.state.wrapping_add(bytes.len() as u64);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## When #[inline(always)] Helps
|
|
56
|
-
|
|
57
|
-
```rust
|
|
58
|
-
// ✅ Tiny functions in hot inner loops
|
|
59
|
-
#[inline(always)]
|
|
60
|
-
fn fast_hash(a: u64, b: u64) -> u64 {
|
|
61
|
-
a.wrapping_mul(b).wrapping_add(a)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ✅ Generic functions that benefit from monomorphization
|
|
65
|
-
#[inline(always)]
|
|
66
|
-
fn swap<T>(a: &mut T, b: &mut T) {
|
|
67
|
-
std::mem::swap(a, b);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ✅ Iterator adapters and closures
|
|
71
|
-
#[inline(always)]
|
|
72
|
-
fn apply<T, F: Fn(T) -> T>(f: F, x: T) -> T {
|
|
73
|
-
f(x)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// ✅ SIMD/vectorization helpers
|
|
77
|
-
#[inline(always)]
|
|
78
|
-
fn add_simd(a: &[f32], b: &[f32], out: &mut [f32]) {
|
|
79
|
-
// ...
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Inline Variants
|
|
84
|
-
|
|
85
|
-
```rust
|
|
86
|
-
// #[inline] - hint to inline, compiler may ignore
|
|
87
|
-
#[inline]
|
|
88
|
-
fn suggested_inline(x: i32) -> i32 { x + 1 }
|
|
89
|
-
|
|
90
|
-
// #[inline(always)] - force inline (almost always)
|
|
91
|
-
#[inline(always)]
|
|
92
|
-
fn force_inline(x: i32) -> i32 { x + 1 }
|
|
93
|
-
|
|
94
|
-
// #[inline(never)] - prevent inlining (for profiling, code size)
|
|
95
|
-
#[inline(never)]
|
|
96
|
-
fn no_inline(x: i32) -> i32 { x + 1 }
|
|
97
|
-
|
|
98
|
-
// No annotation - compiler decides based on heuristics
|
|
99
|
-
fn compiler_decides(x: i32) -> i32 { x + 1 }
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Measuring Inline Impact
|
|
103
|
-
|
|
104
|
-
```rust
|
|
105
|
-
// Use criterion to benchmark
|
|
106
|
-
use criterion::{criterion_group, criterion_main, Criterion};
|
|
107
|
-
|
|
108
|
-
fn bench_with_inline(c: &mut Criterion) {
|
|
109
|
-
c.bench_function("hot_path_inline", |b| {
|
|
110
|
-
b.iter(|| hot_loop())
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Compare binary sizes
|
|
115
|
-
// cargo bloat --release --crates
|
|
116
|
-
|
|
117
|
-
// Check if function was inlined
|
|
118
|
-
// cargo asm --rust my_crate::hot_function
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Generic Functions
|
|
122
|
-
|
|
123
|
-
```rust
|
|
124
|
-
// Generic functions across crate boundaries often need #[inline]
|
|
125
|
-
// Because the generic code is compiled in the calling crate
|
|
126
|
-
|
|
127
|
-
// In library crate:
|
|
128
|
-
#[inline] // Allow inlining in downstream crates
|
|
129
|
-
pub fn generic_function<T: Display>(x: T) {
|
|
130
|
-
println!("{}", x);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Without #[inline], the generic function can't be inlined
|
|
134
|
-
// across crate boundaries even if beneficial
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## See Also
|
|
138
|
-
|
|
139
|
-
- [opt-inline-small](./opt-inline-small.md) - Regular inline for small functions
|
|
140
|
-
- [opt-inline-never-cold](./opt-inline-never-cold.md) - Preventing inlining
|
|
141
|
-
- [perf-profile-first](./perf-profile-first.md) - Profile before optimizing
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# opt-inline-never-cold
|
|
2
|
-
|
|
3
|
-
> Use `#[inline(never)]` and `#[cold]` for error paths and rarely-executed code
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Inlining error handling code into hot paths wastes instruction cache space and can prevent other optimizations. `#[inline(never)]` keeps cold code out of the hot path. `#[cold]` tells the compiler this branch is unlikely, enabling better branch prediction hints and code layout.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
fn process_data(data: &[u8]) -> Result<Output, Error> {
|
|
13
|
-
if data.is_empty() {
|
|
14
|
-
// Error path inlined into hot function
|
|
15
|
-
return Err(Error::Empty {
|
|
16
|
-
context: format!("Expected data, got empty slice"),
|
|
17
|
-
suggestions: vec!["Check input", "Validate before calling"],
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Hot path - now polluted with error construction code
|
|
22
|
-
do_processing(data)
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Good
|
|
27
|
-
|
|
28
|
-
```rust
|
|
29
|
-
fn process_data(data: &[u8]) -> Result<Output, Error> {
|
|
30
|
-
if data.is_empty() {
|
|
31
|
-
return Err(empty_data_error()); // Cold path stays small
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
do_processing(data)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
#[cold]
|
|
38
|
-
#[inline(never)]
|
|
39
|
-
fn empty_data_error() -> Error {
|
|
40
|
-
Error::Empty {
|
|
41
|
-
context: format!("Expected data, got empty slice"),
|
|
42
|
-
suggestions: vec!["Check input", "Validate before calling"],
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## #[cold] for Unlikely Branches
|
|
48
|
-
|
|
49
|
-
```rust
|
|
50
|
-
fn parse_value(input: &str) -> Result<i32, ParseError> {
|
|
51
|
-
match input.parse() {
|
|
52
|
-
Ok(n) => Ok(n),
|
|
53
|
-
Err(e) => cold_parse_error(input, e),
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
#[cold]
|
|
58
|
-
fn cold_parse_error(input: &str, e: std::num::ParseIntError) -> Result<i32, ParseError> {
|
|
59
|
-
Err(ParseError {
|
|
60
|
-
input: input.to_string(),
|
|
61
|
-
source: e,
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Panic Paths
|
|
67
|
-
|
|
68
|
-
```rust
|
|
69
|
-
fn get_index(&self, idx: usize) -> &T {
|
|
70
|
-
if idx >= self.len {
|
|
71
|
-
cold_out_of_bounds(idx, self.len);
|
|
72
|
-
}
|
|
73
|
-
unsafe { self.ptr.add(idx).as_ref().unwrap() }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
#[cold]
|
|
77
|
-
#[inline(never)]
|
|
78
|
-
fn cold_out_of_bounds(idx: usize, len: usize) -> ! {
|
|
79
|
-
panic!("index {} out of bounds for length {}", idx, len);
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Error Construction Functions
|
|
84
|
-
|
|
85
|
-
```rust
|
|
86
|
-
// Keep error construction out of hot path
|
|
87
|
-
impl MyError {
|
|
88
|
-
#[cold]
|
|
89
|
-
pub fn io_error(source: std::io::Error, path: &Path) -> Self {
|
|
90
|
-
MyError::Io {
|
|
91
|
-
source,
|
|
92
|
-
path: path.to_path_buf(),
|
|
93
|
-
context: get_context(),
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
#[cold]
|
|
98
|
-
pub fn validation_error(msg: &str, field: &str) -> Self {
|
|
99
|
-
MyError::Validation {
|
|
100
|
-
message: msg.to_string(),
|
|
101
|
-
field: field.to_string(),
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
fn read_config(path: &Path) -> Result<Config, MyError> {
|
|
107
|
-
std::fs::read_to_string(path)
|
|
108
|
-
.map_err(|e| MyError::io_error(e, path))?
|
|
109
|
-
.parse()
|
|
110
|
-
.map_err(|e| MyError::parse_error(e))
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## likely/unlikely Hints
|
|
115
|
-
|
|
116
|
-
```rust
|
|
117
|
-
// Nightly: intrinsics for branch hints
|
|
118
|
-
#![feature(core_intrinsics)]
|
|
119
|
-
use std::intrinsics::{likely, unlikely};
|
|
120
|
-
|
|
121
|
-
fn process(data: Option<&Data>) -> Result<Output, Error> {
|
|
122
|
-
if unlikely(data.is_none()) {
|
|
123
|
-
return cold_none_error();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
let data = data.unwrap();
|
|
127
|
-
|
|
128
|
-
if likely(data.is_valid()) {
|
|
129
|
-
fast_process(data)
|
|
130
|
-
} else {
|
|
131
|
-
slow_validate_and_process(data)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Stable alternative: structure code so hot path is "fall through"
|
|
136
|
-
fn process(data: Option<&Data>) -> Result<Output, Error> {
|
|
137
|
-
let data = match data {
|
|
138
|
-
Some(d) => d,
|
|
139
|
-
None => return cold_none_error(), // Early return = unlikely hint
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// Compiler assumes code after early returns is "hot"
|
|
143
|
-
fast_process(data)
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Pattern: Extract Cold Code
|
|
148
|
-
|
|
149
|
-
```rust
|
|
150
|
-
// Before: cold code inline
|
|
151
|
-
fn hot_function(x: i32) -> i32 {
|
|
152
|
-
if x < 0 {
|
|
153
|
-
log::error!("Negative value: {}", x);
|
|
154
|
-
eprintln!("Debug info: {:?}", std::backtrace::Backtrace::capture());
|
|
155
|
-
return 0;
|
|
156
|
-
}
|
|
157
|
-
x * 2
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// After: cold code extracted
|
|
161
|
-
fn hot_function(x: i32) -> i32 {
|
|
162
|
-
if x < 0 {
|
|
163
|
-
return handle_negative(x);
|
|
164
|
-
}
|
|
165
|
-
x * 2
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
#[cold]
|
|
169
|
-
#[inline(never)]
|
|
170
|
-
fn handle_negative(x: i32) -> i32 {
|
|
171
|
-
log::error!("Negative value: {}", x);
|
|
172
|
-
eprintln!("Debug info: {:?}", std::backtrace::Backtrace::capture());
|
|
173
|
-
0
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## See Also
|
|
178
|
-
|
|
179
|
-
- [opt-inline-small](./opt-inline-small.md) - Inlining for hot code
|
|
180
|
-
- [opt-inline-always-rare](./opt-inline-always-rare.md) - Forced inlining
|
|
181
|
-
- [err-result-over-panic](./err-result-over-panic.md) - Error handling patterns
|