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,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
@@ -1,156 +0,0 @@
1
- # mem-with-capacity
2
-
3
- > Use `with_capacity()` when size is known
4
-
5
- ## Why It Matters
6
-
7
- When you know (or can estimate) the final size of a collection, pre-allocating avoids multiple reallocations as it grows. Each reallocation copies all existing elements, so avoiding them can dramatically improve performance.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Vec starts at capacity 0, reallocates at 4, 8, 16, 32...
13
- let mut results = Vec::new();
14
- for i in 0..1000 {
15
- results.push(process(i)); // ~10 reallocations!
16
- }
17
-
18
- // String grows similarly
19
- let mut output = String::new();
20
- for word in words {
21
- output.push_str(word);
22
- output.push(' ');
23
- }
24
-
25
- // HashMap default capacity is small
26
- let mut map = HashMap::new();
27
- for (k, v) in pairs { // Many reallocations
28
- map.insert(k, v);
29
- }
30
- ```
31
-
32
- ## Good
33
-
34
- ```rust
35
- // Pre-allocate exact size
36
- let mut results = Vec::with_capacity(1000);
37
- for i in 0..1000 {
38
- results.push(process(i)); // Zero reallocations!
39
- }
40
-
41
- // Or use collect with size hint (iterator provides capacity)
42
- let results: Vec<_> = (0..1000).map(process).collect();
43
-
44
- // Pre-allocate string
45
- let estimated_len = words.iter().map(|w| w.len() + 1).sum();
46
- let mut output = String::with_capacity(estimated_len);
47
- for word in words {
48
- output.push_str(word);
49
- output.push(' ');
50
- }
51
-
52
- // Pre-allocate HashMap
53
- let mut map = HashMap::with_capacity(pairs.len());
54
- for (k, v) in pairs {
55
- map.insert(k, v);
56
- }
57
- ```
58
-
59
- ## Collection Capacity Methods
60
-
61
- ```rust
62
- // Vec
63
- let mut v = Vec::with_capacity(100);
64
- v.reserve(50); // Ensure at least 50 more slots
65
- v.reserve_exact(50); // Ensure exactly 50 more (no extra)
66
- v.shrink_to_fit(); // Release unused capacity
67
-
68
- // String
69
- let mut s = String::with_capacity(100);
70
- s.reserve(50);
71
-
72
- // HashMap / HashSet
73
- let mut m = HashMap::with_capacity(100);
74
- m.reserve(50);
75
-
76
- // VecDeque
77
- let mut d = VecDeque::with_capacity(100);
78
- ```
79
-
80
- ## Estimating Capacity
81
-
82
- ```rust
83
- // From iterator length
84
- fn collect_results(items: &[Item]) -> Vec<Output> {
85
- let mut results = Vec::with_capacity(items.len());
86
- for item in items {
87
- results.push(process(item));
88
- }
89
- results
90
- }
91
-
92
- // From filter estimate (if ~10% pass filter)
93
- fn filter_valid(items: &[Item]) -> Vec<&Item> {
94
- let mut valid = Vec::with_capacity(items.len() / 10);
95
- for item in items {
96
- if item.is_valid() {
97
- valid.push(item);
98
- }
99
- }
100
- valid
101
- }
102
-
103
- // String from parts
104
- fn join_with_sep(parts: &[&str], sep: &str) -> String {
105
- let total_len: usize = parts.iter().map(|p| p.len()).sum();
106
- let sep_len = if parts.is_empty() { 0 } else { sep.len() * (parts.len() - 1) };
107
-
108
- let mut result = String::with_capacity(total_len + sep_len);
109
- for (i, part) in parts.iter().enumerate() {
110
- if i > 0 {
111
- result.push_str(sep);
112
- }
113
- result.push_str(part);
114
- }
115
- result
116
- }
117
- ```
118
-
119
- ## Evidence from Production Code
120
-
121
- From fd (file finder):
122
- ```rust
123
- // https://github.com/sharkdp/fd/blob/master/src/walk.rs
124
- struct ReceiverBuffer<'a, W> {
125
- buffer: Vec<DirEntry>,
126
- // ...
127
- }
128
-
129
- impl<'a, W: Write> ReceiverBuffer<'a, W> {
130
- fn new(...) -> Self {
131
- Self {
132
- buffer: Vec::with_capacity(MAX_BUFFER_LENGTH),
133
- // ...
134
- }
135
- }
136
- }
137
- ```
138
-
139
- ## When to Skip
140
-
141
- ```rust
142
- // Unknown size, small expected
143
- let mut small: Vec<i32> = Vec::new(); // OK for small collections
144
-
145
- // Using collect() with good size_hint
146
- let v: Vec<_> = iter.collect(); // collect() uses size_hint
147
-
148
- // Capacity overhead exceeds benefit
149
- let mut rarely_used = Vec::new(); // OK if rarely grown
150
- ```
151
-
152
- ## See Also
153
-
154
- - [mem-reuse-collections](mem-reuse-collections.md) - Reuse collections with clear()
155
- - [mem-smallvec](mem-smallvec.md) - Use SmallVec for usually-small collections
156
- - [perf-extend-batch](perf-extend-batch.md) - Use extend() for batch insertions
@@ -1,172 +0,0 @@
1
- # mem-write-over-format
2
-
3
- > Use `write!()` into existing buffers instead of `format!()` allocations
4
-
5
- ## Why It Matters
6
-
7
- `format!()` always allocates a new `String`. In hot paths or loops, these allocations add up. `write!()` writes directly into an existing buffer, reusing its capacity. For high-frequency formatting operations, this can eliminate significant allocator overhead.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- fn log_event(event: &Event, output: &mut Vec<u8>) {
13
- // format! allocates a new String every call
14
- let line = format!(
15
- "[{}] {}: {}\n",
16
- event.timestamp,
17
- event.level,
18
- event.message
19
- );
20
- output.extend_from_slice(line.as_bytes());
21
- }
22
-
23
- fn build_response(items: &[Item]) -> String {
24
- let mut result = String::new();
25
-
26
- for item in items {
27
- // format! allocates for each item
28
- result.push_str(&format!("{}: {}\n", item.name, item.value));
29
- }
30
-
31
- result
32
- }
33
- ```
34
-
35
- ## Good
36
-
37
- ```rust
38
- use std::fmt::Write;
39
-
40
- fn log_event(event: &Event, output: &mut Vec<u8>) {
41
- use std::io::Write;
42
- // write! to Vec<u8> directly, no intermediate allocation
43
- write!(
44
- output,
45
- "[{}] {}: {}\n",
46
- event.timestamp,
47
- event.level,
48
- event.message
49
- ).unwrap();
50
- }
51
-
52
- fn build_response(items: &[Item]) -> String {
53
- use std::fmt::Write;
54
-
55
- let mut result = String::with_capacity(items.len() * 64);
56
-
57
- for item in items {
58
- // write! into existing String, reuses capacity
59
- write!(&mut result, "{}: {}\n", item.name, item.value).unwrap();
60
- }
61
-
62
- result
63
- }
64
- ```
65
-
66
- ## Write Trait Varieties
67
-
68
- ```rust
69
- // std::fmt::Write - for String, &mut String
70
- use std::fmt::Write as FmtWrite;
71
- let mut s = String::new();
72
- write!(&mut s, "Hello {}", 42).unwrap();
73
-
74
- // std::io::Write - for Vec<u8>, File, TcpStream, etc.
75
- use std::io::Write as IoWrite;
76
- let mut v: Vec<u8> = Vec::new();
77
- write!(&mut v, "Hello {}", 42).unwrap();
78
-
79
- // Both can fail in principle, but String/Vec never fail
80
- // Still need .unwrap() due to Result return type
81
- ```
82
-
83
- ## Reusable Formatting Buffer
84
-
85
- ```rust
86
- use std::fmt::Write;
87
-
88
- struct Formatter {
89
- buffer: String,
90
- }
91
-
92
- impl Formatter {
93
- fn new() -> Self {
94
- Self { buffer: String::with_capacity(1024) }
95
- }
96
-
97
- fn format_event(&mut self, event: &Event) -> &str {
98
- self.buffer.clear(); // Reuse allocation
99
- write!(
100
- &mut self.buffer,
101
- "[{}] {}",
102
- event.timestamp,
103
- event.message
104
- ).unwrap();
105
- &self.buffer
106
- }
107
- }
108
-
109
- // Usage
110
- let mut formatter = Formatter::new();
111
- for event in events {
112
- let formatted = formatter.format_event(event);
113
- send_log(formatted);
114
- }
115
- ```
116
-
117
- ## writeln! for Lines
118
-
119
- ```rust
120
- use std::fmt::Write;
121
-
122
- let mut output = String::new();
123
-
124
- // writeln! adds newline automatically
125
- writeln!(&mut output, "Line 1: {}", value1).unwrap();
126
- writeln!(&mut output, "Line 2: {}", value2).unwrap();
127
-
128
- // Equivalent to
129
- write!(&mut output, "Line 1: {}\n", value1).unwrap();
130
- ```
131
-
132
- ## When format! Is Fine
133
-
134
- ```rust
135
- // One-time formatting, not in loop
136
- let message = format!("Starting server on port {}", port);
137
- log::info!("{}", message);
138
-
139
- // Return value (can't return reference to local buffer)
140
- fn describe(item: &Item) -> String {
141
- format!("{}: {}", item.name, item.value) // Must allocate
142
- }
143
-
144
- // Debug/error paths (not hot)
145
- if condition {
146
- panic!("Unexpected: {}", format!("details: {:?}", debug_info));
147
- }
148
- ```
149
-
150
- ## Benchmark Difference
151
-
152
- ```rust
153
- // format! in loop: ~500ns per iteration (allocation heavy)
154
- for i in 0..1000 {
155
- let s = format!("item-{}", i);
156
- process(&s);
157
- }
158
-
159
- // write! with reuse: ~50ns per iteration (no allocation)
160
- let mut buf = String::with_capacity(32);
161
- for i in 0..1000 {
162
- buf.clear();
163
- write!(&mut buf, "item-{}", i).unwrap();
164
- process(&buf);
165
- }
166
- ```
167
-
168
- ## See Also
169
-
170
- - [mem-avoid-format](./mem-avoid-format.md) - General format! avoidance patterns
171
- - [mem-reuse-collections](./mem-reuse-collections.md) - Reusing buffers in loops
172
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating string capacity
@@ -1,164 +0,0 @@
1
- # mem-zero-copy
2
-
3
- > Use zero-copy patterns with slices and `Bytes`
4
-
5
- ## Why It Matters
6
-
7
- Zero-copy means working with data without copying it. Instead of allocating new memory and copying bytes, you work with references to the original data. This dramatically reduces memory usage and improves performance, especially for large data.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Copies every line into a new String
13
- fn get_lines(data: &str) -> Vec<String> {
14
- data.lines()
15
- .map(|line| line.to_string()) // Allocates!
16
- .collect()
17
- }
18
-
19
- // Copies the entire buffer
20
- fn process_packet(buffer: &[u8]) -> Vec<u8> {
21
- let header = buffer[0..16].to_vec(); // Copy!
22
- let body = buffer[16..].to_vec(); // Copy!
23
- // Process...
24
- [header, body].concat() // Another copy!
25
- }
26
- ```
27
-
28
- ## Good
29
-
30
- ```rust
31
- // Zero-copy: returns references to original data
32
- fn get_lines(data: &str) -> Vec<&str> {
33
- data.lines().collect() // Just pointers!
34
- }
35
-
36
- // Zero-copy with slices
37
- fn process_packet(buffer: &[u8]) -> (&[u8], &[u8]) {
38
- let header = &buffer[0..16]; // Just a pointer + length
39
- let body = &buffer[16..]; // Just a pointer + length
40
- (header, body)
41
- }
42
- ```
43
-
44
- ## Using bytes::Bytes
45
-
46
- ```rust
47
- use bytes::Bytes;
48
-
49
- // Bytes provides zero-copy slicing with reference counting
50
- let data = Bytes::from("hello world");
51
-
52
- // Slicing doesn't copy - just increments refcount
53
- let hello = data.slice(0..5); // Zero-copy!
54
- let world = data.slice(6..11); // Zero-copy!
55
-
56
- // Both hello and world share the underlying allocation
57
- // Memory is freed when all references are dropped
58
- ```
59
-
60
- ## Real-World Pattern from Deno
61
-
62
- ```rust
63
- // https://github.com/denoland/deno/blob/main/ext/http/lib.rs
64
- fn method_to_cow(method: &http::Method) -> Cow<'static, str> {
65
- match *method {
66
- Method::GET => Cow::Borrowed("GET"), // Zero-copy
67
- Method::POST => Cow::Borrowed("POST"), // Zero-copy
68
- Method::PUT => Cow::Borrowed("PUT"), // Zero-copy
69
- _ => Cow::Owned(method.to_string()), // Only copies for rare methods
70
- }
71
- }
72
- ```
73
-
74
- ## Zero-Copy Parsing
75
-
76
- ```rust
77
- // Bad: Copies each parsed field
78
- struct ParsedBad {
79
- name: String,
80
- value: String,
81
- }
82
-
83
- fn parse_bad(input: &str) -> ParsedBad {
84
- let (name, value) = input.split_once('=').unwrap();
85
- ParsedBad {
86
- name: name.to_string(), // Copy!
87
- value: value.to_string(), // Copy!
88
- }
89
- }
90
-
91
- // Good: References into original string
92
- struct Parsed<'a> {
93
- name: &'a str,
94
- value: &'a str,
95
- }
96
-
97
- fn parse_good(input: &str) -> Parsed<'_> {
98
- let (name, value) = input.split_once('=').unwrap();
99
- Parsed { name, value } // Zero-copy!
100
- }
101
- ```
102
-
103
- ## Combining with Cow
104
-
105
- ```rust
106
- use std::borrow::Cow;
107
-
108
- // Zero-copy when possible, copy when needed
109
- fn normalize<'a>(input: &'a str) -> Cow<'a, str> {
110
- if input.contains('\t') {
111
- // Must copy to modify
112
- Cow::Owned(input.replace('\t', " "))
113
- } else {
114
- // Zero-copy reference
115
- Cow::Borrowed(input)
116
- }
117
- }
118
- ```
119
-
120
- ## memchr for Fast Searching
121
-
122
- ```rust
123
- use memchr::memchr;
124
-
125
- // Fast byte search using SIMD
126
- fn find_newline(data: &[u8]) -> Option<usize> {
127
- memchr(b'\n', data) // SIMD-accelerated, no allocation
128
- }
129
-
130
- // Find all occurrences
131
- use memchr::memchr_iter;
132
-
133
- fn count_newlines(data: &[u8]) -> usize {
134
- memchr_iter(b'\n', data).count()
135
- }
136
- ```
137
-
138
- ## When Zero-Copy Isn't Possible
139
-
140
- ```rust
141
- // Need to modify data - must copy
142
- fn uppercase(s: &str) -> String {
143
- s.to_uppercase() // Creates new String
144
- }
145
-
146
- // Need data to outlive source
147
- fn store_for_later(s: &str) -> String {
148
- s.to_string() // Must copy for ownership
149
- }
150
-
151
- // Cross-thread transfer (without Arc)
152
- fn send_to_thread(data: &[u8]) {
153
- let owned = data.to_vec(); // Must copy
154
- std::thread::spawn(move || {
155
- process(&owned);
156
- });
157
- }
158
- ```
159
-
160
- ## See Also
161
-
162
- - [own-cow-conditional](own-cow-conditional.md) - Use Cow for conditional ownership
163
- - [own-borrow-over-clone](own-borrow-over-clone.md) - Prefer borrowing over cloning
164
- - [mem-arena-allocator](mem-arena-allocator.md) - Arena allocators for batch operations