performance-tuning — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited performance-tuning (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Measure first. Optimize second. Verify improvement with data.
The diagnostic workflow is: measure → identify the bottleneck → optimize → benchmark. If your host also exposes a profiling-tool skill (cProfile flags, memory profiler setup), use it alongside this workflow — this skill owns the method, that owns the tool syntax.
Premature optimization checklist — if ANY of these are true, stop and reconsider:
Only proceed when: (1) you have a measured bottleneck and (2) it actually impacts the user.
# Profile a script
python -m cProfile -s cumtime your_script.py
# Profile with output to file (for large reports)
python -m cProfile -o profile.out your_script.py
python -c "import pstats; p = pstats.Stats('profile.out'); p.sort_stats('cumulative'); p.print_stats(20)"pip install memory_profiler
# Add @profile decorator to the function
# Then run:
python -m memory_profiler your_script.pypip install line_profiler
# Add @profile decorator to the function
# Then run:
kernprof -l -v your_script.py# Built-in profiler
node --prof your_script.js
# Analyze output
node --prof-process isolate-*.log > profile.txtWhat to look for:
cumtime (Python) — total time spent in function including callees → find the top offenderstottime (Python) — time in function excluding callees → find the actual slow codeHot-loop amplification: Look for functions called thousands of times inside a tight loop (per frame, per row, per request, per event). One slow function called 10,000 times = 10,000x the pain. Pull invariant work out of the loop.
Vectorize with pandas/numpy instead of loops:
# SLOW: Python loop over DataFrame
for i, row in df.iterrows():
result.append(row['price'] * row['qty'])
# FAST: Vectorized operation
result = df['price'] * df['qty']Chunk large DataFrames:
# Process in chunks instead of loading all data at once
for chunk in pd.read_csv('large_file.csv', chunksize=10000):
process(chunk)Use sets for membership testing:
# SLOW: O(n) list lookup
if item in my_list: # searches entire list
# FAST: O(1) set lookup
if item in my_set:Cache expensive computations:
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_calc(n: int) -> float:
... # computed once, cached afterA common bottleneck in any tick-by-tick or row-by-row pipeline: recomputing a derived series on every iteration when it could be computed once before the loop.
# SLOW: recompute the same indicator on every iteration
for i, row in df.iterrows():
signal = compute_metric_for_one_row(row)
# FAST: pre-compute the entire series once, vectorized
df['metric'] = compute_metric_series(df['value']) # once, vectorized# Add an index on frequently filtered columns
conn.execute("CREATE INDEX IF NOT EXISTS idx_entity_date ON records (entity_id, record_date)")
# Inspect the query plan to see what the engine is doing
conn.execute("EXPLAIN QUERY PLAN SELECT ...") # SQLite; use EXPLAIN ANALYZE on Postgres# SLOW: apply() calls a Python function per row
df['result'] = df.apply(lambda row: complex_calc(row), axis=1)
# FAST: vectorized numpy operation
df['result'] = np.where(df['value'] > threshold, df['a'], df['b'])Always record results. No "I think it's faster now."
## Performance Benchmark — [Feature/Script Name]
Date: YYYY-MM-DD
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| Job runtime (full dataset) | 45s | 8s | 82% faster |
| Memory peak | 2.1 GB | 340 MB | 84% less |
| Rows processed/sec | 1,200 | 8,400 | 7x faster |Commit this table alongside the change so the gain is part of the record, not folklore.
| Situation | Tool |
|---|---|
| "What's slow?" | Python: cProfile -s cumtime |
| "Why is memory high?" | Python: memory_profiler |
| "Which line?" | Python: line_profiler |
| "Node.js bottleneck" | node --prof |
| "pandas loop slow" | Vectorize: replace df.apply(...) / iterrows() with column ops |
| "SQL query slow" | EXPLAIN QUERY PLAN (or EXPLAIN ANALYZE) + add an index |
| "Tick/row loop too slow" | Pre-calculate invariant series before the loop |
Use this skill when:
Phrases that trigger: "this is slow", "optimize", "profile this", "pipeline bottleneck", "memory usage", "benchmark", "it's hanging", "needs to be faster", "latency", "why is this slow".
@lru_cache or a manual cache speeds things up until stale data causes wrong results. Every cache needs a clear invalidation policy — time-based, event-based, or size-based. Unbounded caches also leak memory over long-running processes.| Stage | Skill |
|---|---|
| Before optimizing | Confirm there's a real bottleneck — profile first (this skill) |
| This skill | performance-tuning — measure → optimize → benchmark |
| After optimizing | tdd-workflow — verify behavior unchanged with tests |
| If introduced a regression | debug-session — diagnose what broke |
| Reviewing the optimized change | code-review-session — catch subtle correctness issues |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.