Skip to content
Back to skills

Performance Profiling

ASecurity

Profile and optimize Python/Node.js — cProfile, py-spy, clinic.js, memory profiling, async bottlenecks, DB query analysis

  • 10 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 9, 2026
ai-agentspythonbashsqlnodenodejstestingdebuggingfrontendperformance

Works with

  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 9, 2026

npx -y skills add yanacuti1121/Yana-AI --skill performance-profiling --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Performance Profiling?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Performance Profiling
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yanacuti1121-performance-profiling/badge)](https://www.skillsdirectory.com/skills/yanacuti1121-performance-profiling)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: performance-profiling
description: Profile and optimize Python/Node.js — cProfile, py-spy, clinic.js, memory profiling, async bottlenecks, DB query analysis
triggers:
  - performance profiling
  - profile python
  - profile nodejs
  - cprofile
  - py-spy
  - memory leak python
  - memory profiling
  - slow query analysis
  - performance bottleneck
  - async performance
  - optimize python
do_not_use_for:
  - frontend performance — use web-performance skill
  - load testing — use k6/locust
  - error debugging — use error-handling-patterns
see_also:
  - ai-code-maintainability
  - logging-observability
  - web-performance
---

# Performance Profiling

## Python: cProfile (CPU)

```bash
# Profile entire script
python -m cProfile -s cumulative -o profile.prof my_script.py

# Visualize with snakeviz
pip install snakeviz
snakeviz profile.prof
```

```python
import cProfile
import pstats
from pstats import SortKey

# Profile a specific function
profiler = cProfile.Profile()
profiler.enable()
result = slow_function(data)
profiler.disable()

stats = pstats.Stats(profiler)
stats.sort_stats(SortKey.CUMULATIVE)
stats.print_stats(20)   # top 20 functions by cumulative time
```

## Python: py-spy (Production-safe sampling)

```bash
# Install
pip install py-spy

# Profile running process without restarting
py-spy top --pid 12345              # live top-style view
py-spy record -o profile.svg --pid 12345  # flame graph
py-spy dump --pid 12345             # one-time stack dump

# Profile from start
py-spy record -o profile.svg -- python my_script.py
```

## Python: Memory Profiling

```python
# tracemalloc — built-in, no overhead when not active
import tracemalloc

tracemalloc.start()
# ... run code ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics("lineno")
for stat in top_stats[:10]:
    print(stat)

# memory-profiler — line-by-line
pip install memory-profiler
from memory_profiler import profile

@profile
def process_large_file(path: str) -> None:
    with open(path) as f:
        data = f.read()      # see how much memory this line uses
    process(data)
```

## Python: Async Bottlenecks

```python
import asyncio
import time

# Find which coroutine is slow
async def timed(coro, label: str):
    start = time.perf_counter()
    result = await coro
    elapsed = time.perf_counter() - start
    if elapsed > 0.1:   # log slow coroutines
        print(f"SLOW [{label}]: {elapsed:.3f}s")
    return result

# Profile concurrent tasks
async def main():
    tasks = [
        timed(fetch_user(uid), f"fetch_user({uid})")
        for uid in user_ids
    ]
    results = await asyncio.gather(*tasks)

# Detect event loop blocking
import asyncio

async def detect_blocking(threshold: float = 0.05):
    """Alert if anything blocks the event loop > 50ms."""
    while True:
        t0 = time.perf_counter()
        await asyncio.sleep(0)   # yield to event loop
        elapsed = time.perf_counter() - t0
        if elapsed > threshold:
            print(f"Event loop blocked for {elapsed:.3f}s!")
```

## DB Query Analysis

```python
# SQLAlchemy: log all queries with timing
import logging
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)

# Or use sqlalchemy-utils query profiler
from sqlalchemy_utils import QueryChain

with QueryChain() as qc:
    users = session.execute(select(User)).scalars().all()

print(f"Queries: {qc.count}, Total: {qc.total_time:.3f}s")
for q in qc.queries:
    print(f"  {q.duration:.3f}s — {q.statement[:80]}")

# EXPLAIN ANALYZE for slow queries (PostgreSQL)
from sqlalchemy import text

result = session.execute(text(
    "EXPLAIN ANALYZE SELECT * FROM users WHERE email = :email"
), {"email": "test@example.com"})
for row in result:
    print(row[0])
```

## Node.js: clinic.js

```bash
# Install
npm install -g clinic

# Doctor — quick diagnosis
clinic doctor -- node server.js

# Flame graph — CPU profiling
clinic flame -- node server.js

# Bubble — event loop delays
clinic bubbleprof -- node server.js
```

## Quick Win Checklist

```python
# 1. Avoid repeated attribute lookups in tight loops
# ❌ Slow
for item in items:
    result = self.config.timeout * self.config.multiplier   # 2 lookups per iter

# ✅ Cache outside loop
timeout = self.config.timeout
multiplier = self.config.multiplier
for item in items:
    result = timeout * multiplier

# 2. Use generators for large sequences
# ❌ Creates entire list in memory
data = [transform(x) for x in large_file]

# ✅ Stream processing
data = (transform(x) for x in large_file)

# 3. String concatenation in loops
# ❌ O(n²) — creates new string each iteration
result = ""
for chunk in chunks:
    result += chunk

# ✅ O(n) — join at end
result = "".join(chunks)

# 4. Set/dict lookups vs list membership
# ❌ O(n) per check
allowed = ["admin", "editor", "viewer"]
if role in allowed:

# ✅ O(1) per check
ALLOWED_ROLES = frozenset({"admin", "editor", "viewer"})
if role in ALLOWED_ROLES:
```

## Anti-Fake-Pass Checks

- cProfile adds overhead — don't profile micro-benchmarks with it, use `timeit` instead
- py-spy requires `--sudo` for other user processes on Linux
- Memory profiler `@profile` decorator slows code significantly — remove in prod
- `asyncio.gather()` parallelizes I/O, not CPU — use `ProcessPoolExecutor` for CPU-bound
- "EXPLAIN ANALYZE" actually runs the query — don't use on destructive queries
- Flame graphs show wall clock time — CPU flame graphs only show CPU time, not I/O waits

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.