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.
Files changed (231) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/CLAUDE.md +80 -0
  4. package/template/agent/rules/code-styles.md +31 -32
  5. package/template/agent/rules/debug-confirmation-policy.md +2 -0
  6. package/template/agent/rules/file-length-policy.md +2 -0
  7. package/template/agent/rules/git-policy.md +7 -0
  8. package/template/agent/rules/language-matching.md +2 -0
  9. package/template/agent/rules/scratch-scripts.md +39 -0
  10. package/template/agent/rules/superpowers.md +8 -51
  11. package/template/agent/skills/executing-plans/SKILL.md +17 -0
  12. package/template/agent/skills/systematic-debugging/SKILL.md +16 -0
  13. package/template/agent/skills/test-driven-development/SKILL.md +16 -0
  14. package/template/agent/skills/verification-before-completion/SKILL.md +22 -0
  15. package/template/agent/skills/writing-plans/SKILL.md +16 -0
  16. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  17. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  18. package/template/agent/skills/api-design/SKILL.md +0 -193
  19. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  20. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  21. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  22. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  23. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  24. package/template/agent/skills/community-manager/SKILL.md +0 -115
  25. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  26. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  27. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  28. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  29. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  30. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  31. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  32. package/template/agent/skills/game-design/SKILL.md +0 -194
  33. package/template/agent/skills/game-developer/SKILL.md +0 -175
  34. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  35. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  36. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  37. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  38. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  39. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  40. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  41. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  42. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  43. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  44. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  45. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  46. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  47. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  48. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  53. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  54. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  55. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  56. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  57. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  58. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  59. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  60. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  61. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  62. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  63. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  68. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  69. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  70. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  71. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  72. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  73. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  74. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  75. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  76. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  77. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  78. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  83. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  84. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  85. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  86. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  87. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  88. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  89. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  90. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  91. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  92. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  93. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  94. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  95. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  96. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  97. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  98. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  99. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  100. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  101. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  102. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  103. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  104. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  106. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  107. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  108. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  109. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  110. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  111. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  112. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  113. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  114. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  115. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  116. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  117. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  118. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  119. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  120. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  121. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  122. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  123. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  124. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  125. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  126. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  127. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  132. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  133. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  134. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  135. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  136. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  137. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  138. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  139. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  140. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  141. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  142. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  148. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  149. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  150. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  151. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  152. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  153. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  154. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  155. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  156. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  157. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  158. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  160. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  161. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  162. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  163. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  164. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  165. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  166. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  167. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  168. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  169. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  170. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  172. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  173. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  174. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  175. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  176. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  177. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  179. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  180. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  181. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  182. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  183. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  184. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  185. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  186. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  187. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  188. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  189. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  190. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  191. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  192. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  193. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  194. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  195. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  196. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  197. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  198. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  199. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  200. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  201. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  202. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  203. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  204. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  207. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  208. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  210. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  211. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  212. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  213. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  214. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  215. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  216. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  217. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  218. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  219. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  220. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  221. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  222. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  223. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  224. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  225. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  226. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  227. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  228. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  229. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  230. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  231. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,174 +0,0 @@
1
- # mem-reuse-collections
2
-
3
- > Clear and reuse collections instead of creating new ones in loops
4
-
5
- ## Why It Matters
6
-
7
- Creating new `Vec`, `String`, or `HashMap` instances in hot loops generates significant allocator pressure. Clearing a collection and reusing it keeps the existing capacity, avoiding repeated allocation/deallocation cycles. This is especially impactful for frequently-executed code paths.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- fn process_batches(batches: &[Batch]) -> Vec<Result> {
13
- let mut results = Vec::new();
14
-
15
- for batch in batches {
16
- let mut temp = Vec::new(); // Allocates every iteration
17
-
18
- for item in &batch.items {
19
- temp.push(transform(item));
20
- }
21
-
22
- results.push(aggregate(&temp));
23
- // temp dropped here, deallocation
24
- }
25
-
26
- results
27
- }
28
-
29
- fn format_lines(items: &[Item]) -> String {
30
- let mut output = String::new();
31
-
32
- for item in items {
33
- let line = format!("{}: {}", item.name, item.value); // Allocates
34
- output.push_str(&line);
35
- output.push('\n');
36
- }
37
-
38
- output
39
- }
40
- ```
41
-
42
- ## Good
43
-
44
- ```rust
45
- fn process_batches(batches: &[Batch]) -> Vec<Result> {
46
- let mut results = Vec::with_capacity(batches.len());
47
- let mut temp = Vec::new(); // Allocate once outside loop
48
-
49
- for batch in batches {
50
- temp.clear(); // Reuse allocation, just reset length
51
-
52
- for item in &batch.items {
53
- temp.push(transform(item));
54
- }
55
-
56
- results.push(aggregate(&temp));
57
- // temp keeps its capacity for next iteration
58
- }
59
-
60
- results
61
- }
62
-
63
- fn format_lines(items: &[Item]) -> String {
64
- use std::fmt::Write;
65
-
66
- let mut output = String::new();
67
- let mut line = String::new(); // Reusable buffer
68
-
69
- for item in items {
70
- line.clear();
71
- write!(&mut line, "{}: {}", item.name, item.value).unwrap();
72
- output.push_str(&line);
73
- output.push('\n');
74
- }
75
-
76
- output
77
- }
78
- ```
79
-
80
- ## Clear vs Drain vs New
81
-
82
- ```rust
83
- let mut vec = vec![1, 2, 3, 4, 5];
84
-
85
- // clear(): keeps capacity, O(n) for Drop types
86
- vec.clear();
87
- assert_eq!(vec.len(), 0);
88
- assert!(vec.capacity() >= 5);
89
-
90
- // drain(): returns iterator, clears after iteration
91
- let drained: Vec<_> = vec.drain(..).collect();
92
-
93
- // truncate(): keeps first n elements
94
- vec.truncate(2);
95
-
96
- // Creating new: loses all capacity
97
- vec = Vec::new(); // Capacity gone
98
- ```
99
-
100
- ## HashMap Reuse
101
-
102
- ```rust
103
- use std::collections::HashMap;
104
-
105
- fn count_words_per_line(lines: &[&str]) -> Vec<HashMap<String, usize>> {
106
- let mut results = Vec::with_capacity(lines.len());
107
- let mut counts = HashMap::new(); // Reuse across iterations
108
-
109
- for line in lines {
110
- counts.clear(); // Keeps bucket allocation
111
-
112
- for word in line.split_whitespace() {
113
- *counts.entry(word.to_string()).or_insert(0) += 1;
114
- }
115
-
116
- results.push(counts.clone());
117
- }
118
-
119
- results
120
- }
121
- ```
122
-
123
- ## BufWriter Pattern
124
-
125
- ```rust
126
- use std::io::{BufWriter, Write};
127
-
128
- fn write_many_records(records: &[Record], mut output: impl Write) -> std::io::Result<()> {
129
- // BufWriter reuses its internal buffer
130
- let mut writer = BufWriter::with_capacity(8192, &mut output);
131
- let mut line = String::with_capacity(256); // Reusable formatting buffer
132
-
133
- for record in records {
134
- line.clear();
135
- format_record(record, &mut line);
136
- writer.write_all(line.as_bytes())?;
137
- writer.write_all(b"\n")?;
138
- }
139
-
140
- writer.flush()
141
- }
142
- ```
143
-
144
- ## When to Create Fresh
145
-
146
- ```rust
147
- // When ownership transfer is needed
148
- fn produce_results() -> Vec<Vec<Item>> {
149
- let mut results = Vec::new();
150
-
151
- for batch in batches {
152
- let processed: Vec<Item> = batch.process(); // Ownership transferred
153
- results.push(processed); // Moved into results
154
- }
155
-
156
- results // Each inner Vec is independent
157
- }
158
-
159
- // When thread safety requires it
160
- std::thread::scope(|s| {
161
- for _ in 0..4 {
162
- s.spawn(|| {
163
- let local_buffer = Vec::new(); // Thread-local, can't share
164
- // ...
165
- });
166
- }
167
- });
168
- ```
169
-
170
- ## See Also
171
-
172
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating capacity
173
- - [mem-clone-from](./mem-clone-from.md) - Reusing allocations when cloning
174
- - [mem-write-over-format](./mem-write-over-format.md) - Avoiding format! allocations
@@ -1,159 +0,0 @@
1
- # mem-smaller-integers
2
-
3
- > Use appropriately-sized integers to reduce memory footprint
4
-
5
- ## Why It Matters
6
-
7
- Using `i64` when `i16` suffices wastes 6 bytes per value. In arrays, vectors, and structs with millions of instances, this waste compounds dramatically. Choosing the smallest integer type that fits your domain reduces memory usage and improves cache utilization.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct Pixel {
13
- r: u64, // Color channels 0-255 = 8 bits needed
14
- g: u64, // Using 64 bits = 8x waste
15
- b: u64,
16
- a: u64,
17
- }
18
- // Size: 32 bytes per pixel
19
-
20
- struct HttpStatus {
21
- code: i32, // HTTP codes 100-599 = 10 bits needed
22
- version: i32, // HTTP 1.0, 1.1, 2, 3 = 2 bits needed
23
- }
24
- // Size: 8 bytes per status
25
-
26
- struct GeoPoint {
27
- lat: f64, // -90 to 90
28
- lon: f64, // -180 to 180
29
- }
30
- // Often f32 precision is sufficient for display
31
- ```
32
-
33
- ## Good
34
-
35
- ```rust
36
- struct Pixel {
37
- r: u8,
38
- g: u8,
39
- b: u8,
40
- a: u8,
41
- }
42
- // Size: 4 bytes per pixel (8x smaller!)
43
-
44
- struct HttpStatus {
45
- code: u16, // 100-599 fits in u16
46
- version: u8, // 1, 2, 3 fits in u8
47
- }
48
- // Size: 3 bytes (+ 1 padding = 4 bytes)
49
-
50
- struct GeoPoint {
51
- lat: f32, // ~7 decimal digits precision
52
- lon: f32, // Sufficient for most geo applications
53
- }
54
- // Size: 8 bytes vs 16 bytes
55
- ```
56
-
57
- ## Integer Size Reference
58
-
59
- | Type | Range | Use For |
60
- |------|-------|---------|
61
- | `u8` | 0 to 255 | Bytes, small counts, flags |
62
- | `i8` | -128 to 127 | Small signed values |
63
- | `u16` | 0 to 65,535 | Port numbers, small indices |
64
- | `i16` | -32,768 to 32,767 | Audio samples |
65
- | `u32` | 0 to 4 billion | Array indices, timestamps (seconds) |
66
- | `i32` | ±2 billion | General integers, file offsets |
67
- | `u64` | 0 to 18 quintillion | Large counts, nanosecond timestamps |
68
- | `usize` | Platform-dependent | Array indexing (required by Rust) |
69
-
70
- ## Struct Packing
71
-
72
- ```rust
73
- use std::mem::size_of;
74
-
75
- // Poor ordering - 24 bytes due to padding
76
- struct Wasteful {
77
- a: u8, // 1 byte + 7 padding
78
- b: u64, // 8 bytes
79
- c: u8, // 1 byte + 7 padding
80
- }
81
- assert_eq!(size_of::<Wasteful>(), 24);
82
-
83
- // Better ordering - 16 bytes
84
- struct Efficient {
85
- b: u64, // 8 bytes (aligned)
86
- a: u8, // 1 byte
87
- c: u8, // 1 byte + 6 padding
88
- }
89
- assert_eq!(size_of::<Efficient>(), 16);
90
-
91
- // Even better with smaller types - 10 bytes
92
- struct Compact {
93
- b: u32, // 4 bytes (if u32 suffices)
94
- a: u8, // 1 byte
95
- c: u8, // 1 byte
96
- }
97
- assert_eq!(size_of::<Compact>(), 8); // With padding
98
- ```
99
-
100
- ## Conversion Safety
101
-
102
- ```rust
103
- // Safe: always succeeds (widening)
104
- let small: u8 = 42;
105
- let big: u32 = small.into();
106
-
107
- // Fallible: may overflow (narrowing)
108
- let big: u32 = 1000;
109
- let small: u8 = big.try_into().expect("value out of range");
110
-
111
- // Or use checked conversion
112
- if let Ok(small) = u8::try_from(big) {
113
- use_small(small);
114
- } else {
115
- handle_overflow();
116
- }
117
- ```
118
-
119
- ## Bitflags for Boolean Sets
120
-
121
- ```rust
122
- use bitflags::bitflags;
123
-
124
- // Instead of 8 separate bool fields (8 bytes minimum)
125
- bitflags! {
126
- struct Permissions: u8 {
127
- const READ = 0b0000_0001;
128
- const WRITE = 0b0000_0010;
129
- const EXECUTE = 0b0000_0100;
130
- const DELETE = 0b0000_1000;
131
- }
132
- }
133
- // All 8 flags in 1 byte!
134
-
135
- let perms = Permissions::READ | Permissions::WRITE;
136
- if perms.contains(Permissions::READ) {
137
- // ...
138
- }
139
- ```
140
-
141
- ## NonZero Types for Option Optimization
142
-
143
- ```rust
144
- use std::num::NonZeroU64;
145
-
146
- // Option<u64> = 16 bytes (no null pointer optimization)
147
- assert_eq!(size_of::<Option<u64>>(), 16);
148
-
149
- // Option<NonZeroU64> = 8 bytes (0 represents None)
150
- assert_eq!(size_of::<Option<NonZeroU64>>(), 8);
151
-
152
- let id: Option<NonZeroU64> = NonZeroU64::new(42);
153
- ```
154
-
155
- ## See Also
156
-
157
- - [mem-box-large-variant](./mem-box-large-variant.md) - Optimizing enum sizes
158
- - [mem-assert-type-size](./mem-assert-type-size.md) - Compile-time size checks
159
- - [type-newtype-ids](./type-newtype-ids.md) - Type safety for integer IDs
@@ -1,138 +0,0 @@
1
- # mem-smallvec
2
-
3
- > Use `SmallVec` for usually-small collections
4
-
5
- ## Why It Matters
6
-
7
- `SmallVec<[T; N]>` stores up to N elements inline (on the stack), only allocating on the heap when the size exceeds N. This eliminates heap allocations for the common case while still allowing growth when needed.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Always heap-allocates, even for 1-2 elements
13
- fn get_path_components(path: &str) -> Vec<&str> {
14
- path.split('/').collect() // Usually 2-4 components
15
- }
16
-
17
- // Always heap-allocates for error list
18
- fn validate(input: &Input) -> Vec<ValidationError> {
19
- let mut errors = Vec::new(); // Usually 0-3 errors
20
- // validation logic...
21
- errors
22
- }
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- use smallvec::{smallvec, SmallVec};
29
-
30
- // Stack-allocated for typical paths (1-8 components)
31
- fn get_path_components(path: &str) -> SmallVec<[&str; 8]> {
32
- path.split('/').collect()
33
- }
34
-
35
- // Stack-allocated for typical error counts
36
- fn validate(input: &Input) -> SmallVec<[ValidationError; 4]> {
37
- let mut errors = SmallVec::new();
38
- // validation logic...
39
- errors
40
- }
41
-
42
- // Using smallvec! macro
43
- let v: SmallVec<[i32; 4]> = smallvec![1, 2, 3];
44
- ```
45
-
46
- ## Choosing Capacity N
47
-
48
- ```rust
49
- // Measure your actual data distribution!
50
- // Guidelines:
51
-
52
- // Path components: 4-8 (most paths are shallow)
53
- type PathParts<'a> = SmallVec<[&'a str; 8]>;
54
-
55
- // Function arguments: 4-8 (most functions have few args)
56
- type Args = SmallVec<[Arg; 8]>;
57
-
58
- // AST children: 2-4 (binary ops, if/else, etc.)
59
- type Children = SmallVec<[Node; 4]>;
60
-
61
- // Error accumulation: 2-4 (most inputs have few errors)
62
- type Errors = SmallVec<[Error; 4]>;
63
-
64
- // Attribute lists: 4-8 (most items have few attributes)
65
- type Attrs = SmallVec<[Attribute; 8]>;
66
- ```
67
-
68
- ## Evidence from rust-analyzer
69
-
70
- ```rust
71
- // https://github.com/rust-lang/rust/blob/main/compiler/rustc_expand/src/base.rs
72
- macro_rules! make_stmts_default {
73
- ($me:expr) => {
74
- $me.make_expr().map(|e| {
75
- smallvec![ast::Stmt {
76
- id: ast::DUMMY_NODE_ID,
77
- span: e.span,
78
- kind: ast::StmtKind::Expr(e),
79
- }]
80
- })
81
- }
82
- }
83
- ```
84
-
85
- ## Trade-offs
86
-
87
- ```rust
88
- // SmallVec is slightly larger than Vec
89
- use std::mem::size_of;
90
- // Vec<i32>: 24 bytes (ptr + len + cap)
91
- // SmallVec<[i32; 4]>: 32 bytes (inline storage + len + discriminant)
92
-
93
- // SmallVec has branching overhead on every operation
94
- // (must check if inline or heap)
95
-
96
- // Profile to verify benefit!
97
- ```
98
-
99
- ## When to Use SmallVec vs Alternatives
100
-
101
- | Situation | Use |
102
- |-----------|-----|
103
- | Usually small, sometimes large | `SmallVec<[T; N]>` |
104
- | Always small, fixed max | `ArrayVec<T, N>` |
105
- | Rarely grows past initial | `Vec::with_capacity` |
106
- | No `unsafe` allowed | `TinyVec` |
107
- | Often empty | `ThinVec` |
108
-
109
- ## ArrayVec Alternative
110
-
111
- ```rust
112
- use arrayvec::ArrayVec;
113
-
114
- // Fixed maximum capacity, never heap allocates
115
- // Panics if you exceed capacity
116
- fn parse_rgb(s: &str) -> ArrayVec<u8, 3> {
117
- let mut components = ArrayVec::new();
118
- for part in s.split(',').take(3) {
119
- components.push(part.parse().unwrap());
120
- }
121
- components
122
- }
123
- ```
124
-
125
- ## TinyVec (No Unsafe)
126
-
127
- ```rust
128
- use tinyvec::{tiny_vec, TinyVec};
129
-
130
- // Same concept as SmallVec but 100% safe code
131
- let v: TinyVec<[i32; 4]> = tiny_vec![1, 2, 3];
132
- ```
133
-
134
- ## See Also
135
-
136
- - [mem-arrayvec](mem-arrayvec.md) - Use ArrayVec for fixed-max collections
137
- - [mem-with-capacity](mem-with-capacity.md) - Pre-allocate when size is known
138
- - [mem-thinvec](mem-thinvec.md) - Use ThinVec for often-empty vectors
@@ -1,142 +0,0 @@
1
- # mem-thinvec
2
-
3
- > Use `ThinVec<T>` for nullable collections with minimal overhead
4
-
5
- ## Why It Matters
6
-
7
- Standard `Vec<T>` is 24 bytes even when empty. `ThinVec` from Mozilla's `thin_vec` crate uses a single pointer (8 bytes), storing length and capacity inline with the heap allocation. For Option<Vec<T>> patterns or structs with many optional vecs, this significantly reduces memory overhead.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct TreeNode {
13
- value: i32,
14
- // Each node pays 24 bytes for children, even leaves
15
- children: Vec<TreeNode>, // Most nodes are leaves with empty Vec
16
- }
17
-
18
- // Or using Option<Vec<T>>
19
- struct SparseData {
20
- // Option<Vec> = 24 bytes (Vec is never null-pointer optimized)
21
- tags: Option<Vec<String>>,
22
- metadata: Option<Vec<Metadata>>,
23
- // 48 bytes for usually-None fields
24
- }
25
- ```
26
-
27
- ## Good
28
-
29
- ```rust
30
- use thin_vec::ThinVec;
31
-
32
- struct TreeNode {
33
- value: i32,
34
- // Empty ThinVec is just a null pointer - 8 bytes
35
- children: ThinVec<TreeNode>,
36
- }
37
-
38
- struct SparseData {
39
- // ThinVec empty = 8 bytes each
40
- tags: ThinVec<String>,
41
- metadata: ThinVec<Metadata>,
42
- // 16 bytes vs 48 bytes
43
- }
44
- ```
45
-
46
- ## Memory Layout
47
-
48
- ```rust
49
- use std::mem::size_of;
50
-
51
- // Standard Vec: always 24 bytes
52
- assert_eq!(size_of::<Vec<u8>>(), 24);
53
- assert_eq!(size_of::<Option<Vec<u8>>>(), 24); // No NPO benefit
54
-
55
- // ThinVec: 8 bytes (one pointer)
56
- use thin_vec::ThinVec;
57
- assert_eq!(size_of::<ThinVec<u8>>(), 8);
58
- assert_eq!(size_of::<Option<ThinVec<u8>>>(), 8); // Option is free!
59
- ```
60
-
61
- ## ThinVec vs Vec
62
-
63
- | Feature | `Vec<T>` | `ThinVec<T>` |
64
- |---------|----------|--------------|
65
- | Size (empty) | 24 bytes | 8 bytes |
66
- | Size (non-empty) | 24 bytes | 8 bytes (header on heap) |
67
- | Option<T> optimization | No | Yes |
68
- | Cache locality | Better (len/cap on stack) | Worse (len/cap on heap) |
69
- | Iteration speed | Faster | Slightly slower |
70
- | API compatibility | Full | Vec-like |
71
-
72
- ## When to Use ThinVec
73
-
74
- ```rust
75
- // ✅ Good: Many instances, often empty
76
- struct SparseGraph {
77
- nodes: Vec<Node>,
78
- // Most edges lists are empty or small
79
- edges: Vec<ThinVec<EdgeId>>, // Saves 16 bytes per node
80
- }
81
-
82
- // ✅ Good: Nullable collection field
83
- struct Document {
84
- content: String,
85
- attachments: ThinVec<Attachment>, // Often empty
86
- }
87
-
88
- // ❌ Avoid: Hot loops, performance-critical iteration
89
- fn process_hot_path(data: &ThinVec<Item>) {
90
- // Every length check goes through pointer indirection
91
- for item in data { // Vec would be faster here
92
- process(item);
93
- }
94
- }
95
-
96
- // ❌ Avoid: Few instances
97
- fn main() {
98
- let single_vec: ThinVec<i32> = ThinVec::new();
99
- // Saving 16 bytes once is meaningless
100
- }
101
- ```
102
-
103
- ## API Compatibility
104
-
105
- ```rust
106
- use thin_vec::{ThinVec, thin_vec};
107
-
108
- // Constructor macro
109
- let v: ThinVec<i32> = thin_vec![1, 2, 3];
110
-
111
- // Familiar Vec-like API
112
- let mut v = ThinVec::new();
113
- v.push(1);
114
- v.push(2);
115
- v.extend([3, 4, 5]);
116
- v.pop();
117
-
118
- // Iteration
119
- for item in &v {
120
- println!("{}", item);
121
- }
122
-
123
- // Slicing
124
- let slice: &[i32] = &v[..];
125
-
126
- // Conversion
127
- let vec: Vec<i32> = v.into();
128
- let thin: ThinVec<i32> = vec.into();
129
- ```
130
-
131
- ## Cargo.toml
132
-
133
- ```toml
134
- [dependencies]
135
- thin-vec = "0.2"
136
- ```
137
-
138
- ## See Also
139
-
140
- - [mem-smallvec](./mem-smallvec.md) - Stack-allocated small vecs
141
- - [mem-boxed-slice](./mem-boxed-slice.md) - Fixed-size heap slices
142
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocation strategies