Отладка, профилирование и хороший стиль
Как находить ошибки, выяснять, что тормозит, и писать код, который потом можно прочитать.
Профилирование — измерение, сколько времени тратит каждая строка кода, чтобы найти узкое место.
Отладка с точками останова
Когда программа ведёт себя не так, помогает пошаговое выполнение. В редакторе ставят точку останова (breakpoint) щелчком слева от строки. При запуске выполнение замрёт на ней, и в Command Window можно осмотреть значения переменных, выполнить выражения, шагнуть дальше. Программно точку задаёт dbstop, продолжение — dbcont, выход — dbquit.
dbstop if error % остановиться при любой ошибке
% запустить программу — отладчик поймает место сбоя
x = 5;
whos % осмотреть переменные на паузе
Особенно полезен dbstop if error: он автоматически останавливает выполнение в точке, где возникла ошибка, и вы видите состояние программы именно в момент сбоя.
Профилирование скорости
Если код медленный, не гадайте — измеряйте. Профайлер показывает, какие строки и функции съедают время. Его запускают вокруг подозрительного кода.
profile on
my_slow_script % запустить анализируемый код
profile viewer % открыть отчёт о времени
Для быстрого замера одного фрагмента есть пара tic/toc: tic запускает секундомер, toc печатает прошедшее время. Это первый инструмент, чтобы проверить, действительно ли векторизация ускорила код.
tic
y = (1:1e6).^2; % векторизованный расчёт
toc % печатает: Elapsed time is ... seconds
Предупреждения редактора
MATLAB-редактор сам подсвечивает проблемные места: неиспользованные переменные, отсутствие точки с запятой в цикле (потенциальный лишний вывод), растущие в цикле массивы без preallocation. Эти подсказки (Code Analyzer, mlint) стоит читать — они часто указывают именно на то, что замедляет код.
Как работает под капотом
Профайлер вставляет в выполнение счётчики, фиксирующие вход и выход каждой функции и время между ними. Поэтому он немного замедляет код, но даёт верную относительную картину: где доля времени велика. Главное правило оптимизации следует прямо из этого: сначала измерь, потом ускоряй. Чаще всего 90% времени уходит на несколько строк — обычно это циклы, которые стоило векторизовать. Оптимизировать что-то ещё до профилирования — почти всегда потеря сил.
Воспроизводимость как страховка
Лучшая отладка — та, которой удалось избежать, и здесь помогает дисциплина воспроизводимости. Скрипт, начинающийся с clear; clc; rng(0);, гарантирует чистый старт и повторяемые случайные числа: запустив его дважды, вы получите тот же результат и сможете уверенно сравнивать «до» и «после» правки. Без этого случайная разница в данных маскируется под баг, и часы уходят на поиск ошибки, которой нет. Разбиение кода на функции с понятными входами и выходами тоже служит отладке: подозрительную функцию можно вызвать изолированно с тестовыми аргументами и проверить её ответ, не запуская всю программу. Эти привычки — чистый старт, фиксированное зерно, изолированные функции — превращают отладку из гадания в методичную проверку, где каждый эксперимент воспроизводим.
Частые ошибки
- Оптимизировать «на глаз» без профайлера — и ускорять не то место.
- Игнорировать подсказки Code Analyzer, которые прямо указывают на проблемы.
- Забыть убрать
dbstopили оставить отладочные выводы в итоговом коде.
Векторизация под микроскопом профайлера
Профилирование особенно ценно для проверки главного навыка курса — векторизации. Легко поверить, что переписанный без циклов код стал быстрее; профайлер и пара tic/toc позволяют это измерить и убедиться. Часто результат впечатляет: цикл, перебиравший миллион элементов секунды, после векторизации отрабатывает за миллисекунды. Но бывает и наоборот — преждевременная «оптимизация» усложняет код, не ускоряя его, потому что узкое место было в другом месте. Профайлер расставляет точки над i: он показывает, что код проводит 95% времени вот в этих трёх строках, и именно их стоит улучшать. Без измерения интуиция о «медленных местах» обманывает удивительно часто.
Читаемость как часть качества
Отладка тем легче, чем чище написан код, поэтому стиль — не косметика, а инвестиция. Осмысленные имена переменных (velocity вместо v2), комментарии, объясняющие «зачем», а не «что», разбиение длинных скриптов на функции, единообразное форматирование — всё это сокращает время будущей отладки, в том числе вашей собственной через месяц. MATLAB поощряет хороший стиль встроенными средствами: Code Analyzer подсвечивает сомнительные места, автоформатирование выравнивает отступы, а функция help читает структурированные комментарии в начале файла как документацию. Привычка писать аккуратно с первого раза окупается каждый раз, когда приходится возвращаться к старому коду и разбираться, что он делает.
Итоги
- Точки останова и
dbstop if errorловят момент сбоя для осмотра переменных. profileиtic/tocпоказывают, где тратится время.- Правило: сначала измерь профайлером, потом оптимизируй узкое место (обычно цикл).