agy-superpowers 5.2.2 → 5.2.3

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 (220) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/scratch-scripts.md +37 -0
  4. package/template/agent/rules/superpowers.md +4 -51
  5. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  6. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  7. package/template/agent/skills/api-design/SKILL.md +0 -193
  8. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  9. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  10. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  11. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  12. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  13. package/template/agent/skills/community-manager/SKILL.md +0 -115
  14. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  15. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  16. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  17. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  18. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  19. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  20. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  21. package/template/agent/skills/game-design/SKILL.md +0 -194
  22. package/template/agent/skills/game-developer/SKILL.md +0 -175
  23. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  24. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  25. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  26. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  27. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  28. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  29. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  30. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  31. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  32. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  33. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  34. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  35. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  36. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  37. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  38. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  39. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  40. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  41. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  42. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  43. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  44. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  45. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  46. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  47. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  48. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  53. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  54. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  55. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  56. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  57. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  58. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  59. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  60. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  61. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  62. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  63. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  68. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  69. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  70. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  71. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  72. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  73. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  74. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  75. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  76. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  77. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  78. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  83. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  84. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  85. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  86. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  87. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  88. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  89. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  90. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  91. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  92. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  93. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  94. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  95. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  96. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  97. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  98. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  99. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  100. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  101. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  102. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  103. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  104. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  106. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  107. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  108. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  109. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  110. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  111. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  113. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  114. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  115. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  116. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  117. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  118. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  119. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  120. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  121. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  122. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  123. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  124. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  125. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  126. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  127. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  132. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  133. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  134. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  135. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  136. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  137. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  138. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  139. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  140. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  141. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  148. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  149. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  150. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  151. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  152. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  153. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  154. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  155. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  156. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  157. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  158. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  160. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  161. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  162. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  163. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  164. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  165. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  166. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  167. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  168. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  169. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  170. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  172. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  173. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  174. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  175. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  176. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  177. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  179. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  180. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  181. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  182. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  183. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  184. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  185. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  186. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  187. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  188. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  189. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  190. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  191. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  192. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  193. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  194. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  195. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  196. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  197. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  198. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  199. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  200. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  201. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  202. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  203. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  204. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  207. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  208. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  210. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  211. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  212. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  213. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  214. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  215. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  216. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  217. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  218. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  219. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  220. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,149 +0,0 @@
1
- # mem-compact-string
2
-
3
- > Use compact string types for memory-constrained string storage
4
-
5
- ## Why It Matters
6
-
7
- Standard `String` is 24 bytes (pointer + length + capacity). For applications storing millions of short strings, this overhead dominates. Compact string libraries like `compact_str`, `smartstring`, or `ecow` store small strings inline (no heap allocation) and use optimized layouts for larger strings.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct User {
13
- id: u64,
14
- // Most usernames are < 24 chars, but String is always 24 bytes + heap
15
- username: String,
16
- email: String,
17
- }
18
-
19
- // 1 million users = 24 bytes * 2 * 1M = 48MB just for String metadata
20
- // Plus all the heap allocations for actual content
21
- ```
22
-
23
- ## Good
24
-
25
- ```rust
26
- use compact_str::CompactString;
27
-
28
- struct User {
29
- id: u64,
30
- // CompactString: 24 bytes, but strings ≤ 24 chars are inline (no heap)
31
- username: CompactString,
32
- email: CompactString,
33
- }
34
-
35
- // Most usernames fit inline = zero heap allocations
36
- // Same memory footprint as String but way fewer allocations
37
- ```
38
-
39
- ## Compact String Libraries
40
-
41
- ### compact_str
42
-
43
- ```rust
44
- use compact_str::CompactString;
45
-
46
- // Inline storage for strings ≤ 24 bytes
47
- let small: CompactString = "hello".into(); // No heap allocation
48
-
49
- // Automatic heap fallback for larger strings
50
- let large: CompactString = "x".repeat(100).into();
51
-
52
- // String-like API
53
- let mut s = CompactString::new("hello");
54
- s.push_str(" world");
55
- assert_eq!(s.as_str(), "hello world");
56
-
57
- // Format macro
58
- use compact_str::format_compact;
59
- let s = format_compact!("value: {}", 42);
60
- ```
61
-
62
- ### smartstring
63
-
64
- ```rust
65
- use smartstring::{SmartString, LazyCompact};
66
-
67
- // Default is LazyCompact: 24 bytes inline capacity
68
- let s: SmartString<LazyCompact> = "short string".into();
69
-
70
- // Compact mode: 23 bytes inline on 64-bit
71
- use smartstring::Compact;
72
- let s: SmartString<Compact> = "hello".into();
73
- ```
74
-
75
- ### ecow (copy-on-write)
76
-
77
- ```rust
78
- use ecow::EcoString;
79
-
80
- // Clone is O(1) - shares underlying data
81
- let s1: EcoString = "shared data".into();
82
- let s2 = s1.clone(); // Cheap, shares allocation
83
-
84
- // Copy-on-write: only allocates on mutation
85
- let mut s3 = s1.clone();
86
- s3.push_str(" modified"); // Now allocates
87
- ```
88
-
89
- ## Memory Comparison
90
-
91
- ```rust
92
- use std::mem::size_of;
93
-
94
- // All 24 bytes, but different inline capacities
95
- assert_eq!(size_of::<String>(), 24);
96
- assert_eq!(size_of::<compact_str::CompactString>(), 24);
97
- assert_eq!(size_of::<smartstring::SmartString>(), 24);
98
- assert_eq!(size_of::<ecow::EcoString>(), 16); // Even smaller!
99
- ```
100
-
101
- ## Inline Capacity
102
-
103
- | Type | Size | Inline Capacity |
104
- |------|------|-----------------|
105
- | `String` | 24 | 0 (always heap) |
106
- | `CompactString` | 24 | 24 bytes |
107
- | `SmartString<LazyCompact>` | 24 | 23 bytes |
108
- | `EcoString` | 16 | 15 bytes |
109
-
110
- ## When to Use
111
-
112
- ```rust
113
- // ✅ Good: Many short strings in memory
114
- struct Dictionary {
115
- words: Vec<CompactString>, // Millions of short words
116
- }
117
-
118
- // ✅ Good: Frequently cloned strings
119
- struct Template {
120
- parts: Vec<EcoString>, // O(1) clone
121
- }
122
-
123
- // ❌ Don't: Hot path string manipulation
124
- fn transform(s: &str) -> String {
125
- // Standard String is optimized for manipulation
126
- s.to_uppercase()
127
- }
128
-
129
- // ❌ Don't: API boundaries (prefer &str or String for interop)
130
- pub fn public_api(input: CompactString) { } // Forces dependency
131
- pub fn public_api(input: impl Into<String>) { } // Better
132
- ```
133
-
134
- ## Cargo.toml
135
-
136
- ```toml
137
- [dependencies]
138
- compact_str = "0.7"
139
- # or
140
- smartstring = "1.0"
141
- # or
142
- ecow = "0.2"
143
- ```
144
-
145
- ## See Also
146
-
147
- - [mem-boxed-slice](./mem-boxed-slice.md) - Box<str> for immutable strings
148
- - [own-cow-conditional](./own-cow-conditional.md) - Cow<str> for borrow-or-own
149
- - [mem-smallvec](./mem-smallvec.md) - Similar concept for Vec
@@ -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