Skip to main content
ClaudeWave
Skill618 repo starsupdated 8d ago

matlab-optimize-performance

This Claude Code skill provides a systematic 7-step workflow for optimizing MATLAB code performance. Use it when you need to identify and fix speed bottlenecks in MATLAB functions or scripts, including establishing baselines with timeit, profiling code to find the true bottleneck, and measuring improvements. It prevents common mistakes like optimizing the wrong target or claiming speedups without measurement.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/matlab/matlab-agentic-toolkit /tmp/matlab-optimize-performance && cp -r /tmp/matlab-optimize-performance/skills-catalog/matlab-software-development/matlab-optimize-performance ~/.claude/skills/matlab-optimize-performance
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# MATLAB Performance Optimization Workflow

Systematic 7-step workflow for finding and fixing performance bottlenecks in MATLAB code.

## When to Use

- User asks to speed up or optimize MATLAB code
- User wants to find why their MATLAB code is slow
- User has a function or script that takes too long to run
- User asks to benchmark or time MATLAB code
- User wants to compare performance before and after a change
- User asks about MATLAB performance best practices

## When NOT to Use

- Optimizing Simulink model simulation speed (use Simulink Profiler)
- The bottleneck is in compiled C/MEX code that can't be changed at the M-code level
- The performance issue is purely I/O-bound (file reads, network, database)
- User wants to write performance *tests* (use the `writing-matlab-perf-tests` skill)

## The 7-Step Workflow

### Step 1: Establish Baseline

Measure current performance so you have a number to improve against.

**For a single function:**
```matlab
f = @() targetFunction(input1, input2);
baseline = timeit(f);
fprintf('Baseline: %.4f s\n', baseline);
```

**For GPU code:**
```matlab
f = @() gpuFunction(gpuInput);
baseline = gputimeit(f);
```

**For a script or multi-step workflow:**
```matlab
% Warmup run (first call includes JIT compilation)
myWorkflow(inputs);

% Timed run
tic;
myWorkflow(inputs);
baseline = toc;
fprintf('Baseline: %.4f s\n', baseline);
```

`timeit` is preferred because it handles warmup and runs multiple samples automatically.

### Step 2: Profile and Analyze

Find where the time is actually spent. Do NOT guess — always profile.

```matlab
profile on;
targetFunction(input1, input2);
profile off;
profile viewer;
```

**Reading profiler results:**

1. **Function summary** — shows total time and self-time per function. Self-time is time spent in that function, not its callees. Start with the highest self-time.
2. **Per-line detail** — click a function name to see time spent on each line. This reveals the exact bottleneck lines.
3. **Call count** — functions called thousands/millions of times are prime optimization targets.

**Tips:**
- Run the profiled code multiple times (in a loop) if it's very fast, so the profiler collects enough samples
- Look at self-time, not total time, to find the true bottleneck
- Drill into functions — the summary page only tells part of the story

### Step 3: Identify Optimization Opportunities

Based on profiling results, identify which patterns apply. Read `references/optimization-patterns.md` for the full catalog.

**High-impact patterns:**

| Pattern | Typical Speedup | Look For |
|---------|----------------|----------|
| Vectorization | 2–200x | Loops doing element-wise math on arrays |
| Preallocation | 2–100x | Arrays growing inside loops (`x = [x; newRow]`) |
| Unnecessary recomputation | 2–50x | Same expensive expression computed multiple times |
| `discretize`/`histcounts` | 2–50x | Loops binning or classifying data |
| Persistent caching | 1.5–95x | Repeated `load()` or expensive object creation |
| Logical indexing | 1.2–5x | Using `find()` just to index into an array |
| `arguments` block | 1.1–1.8x | Functions using `inputParser` |
| Algebraic simplification | 1.5–3x | Redundant `sqrt`, `abs`, or matrix ops |

**Before optimizing, verify the target is worth it:**
- Is self-time > 10% of total? If not, optimizing it won't matter much.
- Is it called in a tight loop? High call count × small time = big total.
- Is it M-code or a built-in? You can't make a built-in faster, but you can often call it fewer times (e.g., pass a matrix to `filtfilt`/`filter` instead of looping over columns).

### Step 4: Implement Optimizations

Apply the patterns identified in Step 3. See `references/optimization-patterns.md` for the full catalog with before/after code examples.

**General principles:**
- Start with the highest-impact pattern from profiling
- Move invariant work out of loops (object creation, option parsing, constant expressions)
- Replace element-wise loops with array operations where possible
- Use purpose-built functions (`discretize`, `cumsum`, `hypot`) instead of hand-written equivalents
- For large data, batch the vectorization to control memory (see Pattern 9 in catalog)

**Example — move invariant work out of loops:**
```matlab
% Before: repeated expensive setup
for i = 1:n
    opts = optimoptions('fminunc', 'Display', 'off');
    result(i) = fminunc(@(x) cost(x, data(i)), x0, opts);
end

% After: setup once
opts = optimoptions('fminunc', 'Display', 'off');
for i = 1:n
    result(i) = fminunc(@(x) cost(x, data(i)), x0, opts);
end
```

### Step 5: Measure Optimized Performance

Re-measure using the same method as Step 1:

```matlab
f = @() optimizedFunction(input1, input2);
optimized = timeit(f);
speedup = baseline / optimized;
fprintf('Optimized: %.4f s (%.2fx speedup)\n', optimized, speedup);
```

A speedup of 1.2x or more is considered significant. Below that, measurement noise makes it hard to be confident the change helped.

### Step 6: Verify Correctness

Every optimization must produce the same results as the original:

```matlab
original = originalFunction(input1, input2);
fast = optimizedFunction(input1, input2);

% Numeric comparison (allows floating-point tolerance)
maxErr = max(abs(original(:) - fast(:)));
fprintf('Max error: %.2e\n', maxErr);
assert(maxErr < 1e-10, 'Results differ beyond tolerance!');
```

For non-numeric outputs:
```matlab
assert(isequal(original, fast), 'Results differ!');
```

If results differ slightly due to floating-point reordering (e.g., summing in a different order), that's usually acceptable. Document the expected tolerance.

### Step 7: Report Results

Summarize what was done and the improvement achieved:

```matlab
fprintf('\n=== Performance Optimization Report ===\n');
fprintf('Target: %s\n', funcName);
fprintf('Baseline: %.4f s\n', baseline);
fprintf('Optimized: %.4f s\n', optimized);
fprintf('Speedup: %.2fx\n', speedup);
fprintf('Correctness: max error = %.2e\n', maxErr);
fprint
matlab-train-networkSkill

>

matlab-driving-data-importerSkill

Import recorded driving sensor data (GPS, camera, lidar, actor tracks, lanes) into scenariobuilder.* objects (GPSData, CameraData, LidarData, ActorTrackData, Trajectory, laneData) and run preprocessing — synchronize, offset correction, crop, normalizeTimestamps, convertTimestamps. Also: compute actor tracks from lidar when no annotations exist, attach camera/lidar mounting + intrinsics, export to MAT/workspace/timetable/script. Use for raw driving dataset files (KITTI, nuScenes, Waymo, Pandaset, ROS/ROS2 bags, .mat, .csv, .mp4) or driving/vehicle/sensor logs that need wrapping. drivingLogAnalyzer (DLA) is OPT-IN ONLY — invoke only on explicit user request ('DLA', 'open in DLA', 'inspect/explore/analyze the recording') or reported sensor problem (sync drift, timestamp mismatch, overlay misalignment). NEVER auto-launch DLA after wrapping (Rule 0). For 'build scenario / export to RoadRunner / drivingScenario / OpenSCENARIO / Unreal / simulate', hand off to matlab-scenario-builder.

matlab-scenario-builderSkill

Generate driving scenes, scenarios, road surfaces, and 3D content from already-wrapped scenariobuilder.* sensor data (GPS, camera, lidar, actor tracks) using Scenario Builder for Automated Driving Toolbox. Use to BUILD, EXPORT, or AUGMENT a virtual scenario/scene/map: ego or actor trajectories, trajectory smoothing, OpenCRG road-surface extraction, 3D asset generation, static-object placement, point-cloud georeferencing + elevation, lane-based ego localization, sensor-fusion tracking, scenario-event extraction (cut-ins, hard brakes, near-misses, ADAS disengagements), or export to RoadRunner, drivingScenario, OpenDRIVE, OpenCRG, OpenSCENARIO, or Unreal Engine. Also: log-to-scenario, scenario harvesting, accident/near-miss reconstruction, SOTIF (ISO 21448) and ISO 26262 scenario coverage, USGS-aerial-lidar scene augmentation, traffic-sign placement from camera+lidar logs. NOT for raw-data import or multi-sensor sync/crop/offset/timestamp normalization — route those to matlab-driving-data-importer.

roadrunner-asset-mappingSkill

>

roadrunner-convert-lanelet2-to-rrhdSkill

>

roadrunner-import-sceneSkill

>

roadrunner-rrhd-authoringSkill

>

matlab-build-simbiology-modelSkill

Build, modify, and diagram SimBiology models — API reference, helper functions, and layout patterns. Use when constructing or editing models programmatically or visually.