opencodekit 0.16.15 → 0.16.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +1 -1
- package/dist/template/.opencode/agent/plan.md +77 -161
- package/dist/template/.opencode/command/create.md +75 -307
- package/dist/template/.opencode/command/design.md +53 -589
- package/dist/template/.opencode/command/handoff.md +76 -180
- package/dist/template/.opencode/command/init.md +45 -211
- package/dist/template/.opencode/command/plan.md +62 -514
- package/dist/template/.opencode/command/pr.md +56 -226
- package/dist/template/.opencode/command/research.md +55 -266
- package/dist/template/.opencode/command/resume.md +33 -138
- package/dist/template/.opencode/command/review-codebase.md +54 -202
- package/dist/template/.opencode/command/ship.md +78 -127
- package/dist/template/.opencode/command/start.md +47 -577
- package/dist/template/.opencode/command/status.md +55 -354
- package/dist/template/.opencode/command/ui-review.md +52 -298
- package/dist/template/.opencode/command/verify.md +36 -250
- package/dist/template/.opencode/memory.db-shm +0 -0
- package/dist/template/.opencode/memory.db-wal +0 -0
- package/dist/template/.opencode/plugin/README.md +8 -4
- package/dist/template/.opencode/plugin/swarm-enforcer.ts +182 -27
- package/dist/template/.opencode/skill/augment-context-engine/SKILL.md +112 -0
- package/dist/template/.opencode/skill/augment-context-engine/mcp.json +6 -0
- package/dist/template/.opencode/skill/core-data-expert/SKILL.md +82 -0
- package/dist/template/.opencode/skill/core-data-expert/references/batch-operations.md +543 -0
- package/dist/template/.opencode/skill/core-data-expert/references/cloudkit-integration.md +259 -0
- package/dist/template/.opencode/skill/core-data-expert/references/concurrency.md +522 -0
- package/dist/template/.opencode/skill/core-data-expert/references/fetch-requests.md +643 -0
- package/dist/template/.opencode/skill/core-data-expert/references/glossary.md +233 -0
- package/dist/template/.opencode/skill/core-data-expert/references/migration.md +393 -0
- package/dist/template/.opencode/skill/core-data-expert/references/model-configuration.md +597 -0
- package/dist/template/.opencode/skill/core-data-expert/references/performance.md +300 -0
- package/dist/template/.opencode/skill/core-data-expert/references/persistent-history.md +553 -0
- package/dist/template/.opencode/skill/core-data-expert/references/project-audit.md +60 -0
- package/dist/template/.opencode/skill/core-data-expert/references/saving.md +574 -0
- package/dist/template/.opencode/skill/core-data-expert/references/stack-setup.md +625 -0
- package/dist/template/.opencode/skill/core-data-expert/references/testing.md +300 -0
- package/dist/template/.opencode/skill/core-data-expert/references/threading.md +589 -0
- package/dist/template/.opencode/skill/swift-concurrency/SKILL.md +246 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/actors.md +640 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/async-algorithms.md +822 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/async-await-basics.md +249 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/async-sequences.md +670 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/core-data.md +533 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/glossary.md +128 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/linting.md +142 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/memory-management.md +542 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/migration.md +1076 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/performance.md +574 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/sendable.md +578 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/tasks.md +604 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/testing.md +565 -0
- package/dist/template/.opencode/skill/swift-concurrency/references/threading.md +452 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/SKILL.md +290 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/animation-advanced.md +351 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/image-optimization.md +286 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/layout-best-practices.md +312 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/liquid-glass.md +377 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/list-patterns.md +153 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/modern-apis.md +400 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/performance-patterns.md +377 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/scroll-patterns.md +305 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/sheet-navigation-patterns.md +292 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/state-management.md +447 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/text-formatting.md +285 -0
- package/dist/template/.opencode/skill/swiftui-expert-skill/references/view-structure.md +276 -0
- package/package.json +1 -1
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# Performance Optimization
|
|
2
|
+
|
|
3
|
+
Optimizing Core Data performance requires understanding where bottlenecks occur and applying targeted solutions.
|
|
4
|
+
|
|
5
|
+
## Profiling with Instruments
|
|
6
|
+
|
|
7
|
+
### Time Profiler
|
|
8
|
+
|
|
9
|
+
1. In Xcode: Product → Profile
|
|
10
|
+
2. Select Time Profiler
|
|
11
|
+
3. Record while using app
|
|
12
|
+
4. Find heaviest stack traces
|
|
13
|
+
|
|
14
|
+
**Look for:**
|
|
15
|
+
- Excessive faulting
|
|
16
|
+
- Slow fetch requests
|
|
17
|
+
- Save operations taking too long
|
|
18
|
+
|
|
19
|
+
### Allocations Instrument
|
|
20
|
+
|
|
21
|
+
1. Product → Profile
|
|
22
|
+
2. Select Allocations
|
|
23
|
+
3. Monitor memory growth
|
|
24
|
+
4. Identify retained objects
|
|
25
|
+
|
|
26
|
+
**Look for:**
|
|
27
|
+
- Unbounded memory growth
|
|
28
|
+
- Objects not being released
|
|
29
|
+
- Large allocations
|
|
30
|
+
|
|
31
|
+
## SQL Debug Logging
|
|
32
|
+
|
|
33
|
+
Enable SQL logging:
|
|
34
|
+
```
|
|
35
|
+
-com.apple.CoreData.SQLDebug 1
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Output:**
|
|
39
|
+
```sql
|
|
40
|
+
CoreData: sql: SELECT Z_PK, ZNAME FROM ZARTICLE WHERE ZVIEWS > ? LIMIT 20
|
|
41
|
+
CoreData: annotation: sql execution time: 0.0023s
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Analyze:**
|
|
45
|
+
- Query complexity
|
|
46
|
+
- Execution time
|
|
47
|
+
- Number of queries (N+1 problem)
|
|
48
|
+
|
|
49
|
+
## Common Performance Issues
|
|
50
|
+
|
|
51
|
+
### 1. N+1 Query Problem
|
|
52
|
+
|
|
53
|
+
**Problem:**
|
|
54
|
+
```swift
|
|
55
|
+
// Fetches articles
|
|
56
|
+
let articles = try context.fetch(Article.fetchRequest())
|
|
57
|
+
|
|
58
|
+
// Each access fires a fault (N queries)
|
|
59
|
+
for article in articles {
|
|
60
|
+
print(article.category?.name) // Fault!
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Solution:**
|
|
65
|
+
```swift
|
|
66
|
+
let fetchRequest = Article.fetchRequest()
|
|
67
|
+
fetchRequest.relationshipKeyPathsForPrefetching = ["category"]
|
|
68
|
+
let articles = try context.fetch(fetchRequest)
|
|
69
|
+
|
|
70
|
+
// No faults fired
|
|
71
|
+
for article in articles {
|
|
72
|
+
print(article.category?.name) // Already loaded
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. Fetching Too Much Data
|
|
77
|
+
|
|
78
|
+
**Problem:**
|
|
79
|
+
```swift
|
|
80
|
+
// Fetches all properties of all objects
|
|
81
|
+
let articles = try context.fetch(Article.fetchRequest())
|
|
82
|
+
let count = articles.count
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Solution:**
|
|
86
|
+
```swift
|
|
87
|
+
// Only counts, doesn't fetch objects
|
|
88
|
+
let count = try context.count(for: Article.fetchRequest())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. Not Using Batch Sizes
|
|
92
|
+
|
|
93
|
+
**Problem:**
|
|
94
|
+
```swift
|
|
95
|
+
// Loads 10,000 objects into memory
|
|
96
|
+
let fetchRequest = Article.fetchRequest()
|
|
97
|
+
let articles = try context.fetch(fetchRequest)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Solution:**
|
|
101
|
+
```swift
|
|
102
|
+
fetchRequest.fetchBatchSize = 20
|
|
103
|
+
// Only loads 20 at a time
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 4. Fetching Unnecessary Properties
|
|
107
|
+
|
|
108
|
+
**Problem:**
|
|
109
|
+
```swift
|
|
110
|
+
// Fetches all properties
|
|
111
|
+
let fetchRequest = Article.fetchRequest()
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Solution:**
|
|
115
|
+
```swift
|
|
116
|
+
fetchRequest.propertiesToFetch = ["name", "creationDate"]
|
|
117
|
+
// Only fetches needed properties
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 5. Saving Too Frequently
|
|
121
|
+
|
|
122
|
+
**Problem:**
|
|
123
|
+
```swift
|
|
124
|
+
for item in items {
|
|
125
|
+
item.processed = true
|
|
126
|
+
try? context.save() // Very slow!
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Solution:**
|
|
131
|
+
```swift
|
|
132
|
+
for item in items {
|
|
133
|
+
item.processed = true
|
|
134
|
+
}
|
|
135
|
+
try? context.save() // Save once
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 6. Not Resetting Context
|
|
139
|
+
|
|
140
|
+
**Problem:**
|
|
141
|
+
```swift
|
|
142
|
+
// Context accumulates objects
|
|
143
|
+
for i in 0..<10000 {
|
|
144
|
+
let article = Article(context: context)
|
|
145
|
+
// Memory grows unbounded
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Solution:**
|
|
150
|
+
```swift
|
|
151
|
+
for i in 0..<10000 {
|
|
152
|
+
let article = Article(context: context)
|
|
153
|
+
|
|
154
|
+
if i % 100 == 0 {
|
|
155
|
+
try? context.save()
|
|
156
|
+
context.reset() // Clear memory
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Memory Management
|
|
162
|
+
|
|
163
|
+
### Context Reset
|
|
164
|
+
|
|
165
|
+
```swift
|
|
166
|
+
context.reset()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**When to use:**
|
|
170
|
+
- After processing large batches
|
|
171
|
+
- When context accumulates many objects
|
|
172
|
+
- To free memory
|
|
173
|
+
|
|
174
|
+
**Caution:** Invalidates all fetched objects from this context.
|
|
175
|
+
|
|
176
|
+
### Refresh Objects
|
|
177
|
+
|
|
178
|
+
```swift
|
|
179
|
+
context.refresh(article, mergeChanges: false)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**When to use:**
|
|
183
|
+
- Discard in-memory changes
|
|
184
|
+
- Free memory for specific object
|
|
185
|
+
- Reload from database
|
|
186
|
+
|
|
187
|
+
### Turn Objects into Faults
|
|
188
|
+
|
|
189
|
+
```swift
|
|
190
|
+
context.refreshAllObjects()
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**When to use:**
|
|
194
|
+
- Free memory across all objects
|
|
195
|
+
- After large operations
|
|
196
|
+
- When memory is constrained
|
|
197
|
+
|
|
198
|
+
## Fetch Request Optimization
|
|
199
|
+
|
|
200
|
+
### Checklist
|
|
201
|
+
|
|
202
|
+
```swift
|
|
203
|
+
let fetchRequest = Article.fetchRequest()
|
|
204
|
+
|
|
205
|
+
// ✅ Set batch size
|
|
206
|
+
fetchRequest.fetchBatchSize = 20
|
|
207
|
+
|
|
208
|
+
// ✅ Limit properties
|
|
209
|
+
fetchRequest.propertiesToFetch = ["name", "views"]
|
|
210
|
+
|
|
211
|
+
// ✅ Prefetch relationships
|
|
212
|
+
fetchRequest.relationshipKeyPathsForPrefetching = ["category"]
|
|
213
|
+
|
|
214
|
+
// ✅ Use predicate to filter
|
|
215
|
+
fetchRequest.predicate = NSPredicate(format: "views > %d", 100)
|
|
216
|
+
|
|
217
|
+
// ✅ Set fetch limit if applicable
|
|
218
|
+
fetchRequest.fetchLimit = 10
|
|
219
|
+
|
|
220
|
+
// ✅ Specify sort descriptors
|
|
221
|
+
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Batch Operations
|
|
225
|
+
|
|
226
|
+
For large-scale operations, use batch requests:
|
|
227
|
+
|
|
228
|
+
```swift
|
|
229
|
+
// Instead of:
|
|
230
|
+
for article in articles {
|
|
231
|
+
article.isRead = true
|
|
232
|
+
}
|
|
233
|
+
try context.save()
|
|
234
|
+
|
|
235
|
+
// Use:
|
|
236
|
+
let batchUpdate = NSBatchUpdateRequest(entityName: "Article")
|
|
237
|
+
batchUpdate.propertiesToUpdate = ["isRead": true]
|
|
238
|
+
try context.execute(batchUpdate)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Benefits:**
|
|
242
|
+
- 10-20x faster
|
|
243
|
+
- Lower memory usage
|
|
244
|
+
- SQL-level operations
|
|
245
|
+
|
|
246
|
+
## Data Generators for Testing
|
|
247
|
+
|
|
248
|
+
Create reproducible test datasets:
|
|
249
|
+
|
|
250
|
+
```swift
|
|
251
|
+
class DataGenerator {
|
|
252
|
+
func generate(count: Int, in context: NSManagedObjectContext) {
|
|
253
|
+
for i in 0..<count {
|
|
254
|
+
let article = Article(context: context)
|
|
255
|
+
article.name = "Article \(i)"
|
|
256
|
+
|
|
257
|
+
if i % 100 == 0 {
|
|
258
|
+
try? context.save()
|
|
259
|
+
context.reset()
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
try? context.save()
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Usage
|
|
267
|
+
let generator = DataGenerator()
|
|
268
|
+
generator.generate(count: 10000, in: backgroundContext)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Profiling Checklist
|
|
272
|
+
|
|
273
|
+
1. **Enable SQL debug** - See actual queries
|
|
274
|
+
2. **Profile with Time Profiler** - Find slow operations
|
|
275
|
+
3. **Profile with Allocations** - Find memory issues
|
|
276
|
+
4. **Test with realistic data** - Small datasets hide problems
|
|
277
|
+
5. **Monitor on device** - Simulator performance differs
|
|
278
|
+
6. **Test on older devices** - Performance varies
|
|
279
|
+
|
|
280
|
+
## Quick Wins
|
|
281
|
+
|
|
282
|
+
1. **Use `count(for:)` instead of fetching** - 100x faster
|
|
283
|
+
2. **Set `fetchBatchSize`** - Reduces memory
|
|
284
|
+
3. **Prefetch relationships** - Eliminates N+1 queries
|
|
285
|
+
4. **Use `propertiesToFetch`** - Reduces data transfer
|
|
286
|
+
5. **Reset context periodically** - Frees memory
|
|
287
|
+
6. **Use batch operations** - 10-20x faster for bulk changes
|
|
288
|
+
7. **Save conditionally** - Check `hasPersistentChanges`
|
|
289
|
+
8. **Use background contexts** - Keep UI responsive
|
|
290
|
+
|
|
291
|
+
## Summary
|
|
292
|
+
|
|
293
|
+
1. **Profile first** - Measure before optimizing
|
|
294
|
+
2. **Use Instruments** - Time Profiler and Allocations
|
|
295
|
+
3. **Enable SQL debug** - Understand query behavior
|
|
296
|
+
4. **Optimize fetch requests** - Batch size, properties, prefetching
|
|
297
|
+
5. **Use batch operations** - For large-scale changes
|
|
298
|
+
6. **Reset contexts** - Free memory periodically
|
|
299
|
+
7. **Test with real data** - Small datasets hide issues
|
|
300
|
+
8. **Monitor on devices** - Real-world performance matters
|