Иллюстрированный самоучитель по практике программирования

Замеры времени и профилирование

Очевидно, что в затратах времени доминируют две функции: strchr и strncmp, причем обе вызываются из strstr. Итак, Кнут ориентирует нас правильно: небольшая часть программы поглощает большую часть времени ее исполнения. При первом профилировании программы очень часто выясняется, что лидирующие в профиле две-три функции поглощают половину времени и более, как в приведенном случае, и, соответственно, становится сразу же ясно, на чем сконцентрировать внимание.

Концентрируйтесь на критических местах.
Переписав strstr, мы еще раз выполнили профилирование для spamtest и выяснили, что теперь 99.8% времени тратит собственно strstr, хотя в целом программа и стала работать быстрее. Когда одна функция является таким явным узким местом программы, существует только два способа исправить положение: улучшить саму функцию, применив более эффективный алгоритм, или избавиться от этой функции вообще, переписав всю программу.

Мы выбрали второй способ – переписали программу. Ниже приведены первые несколько строк профиля работы программы sparest, использующей последнюю, наиболее быструю реализацию isspam. При этом общее время работы программы существенно уменьшилось, критической точкой стала функция memcmp, а isspam стала занимать более существенную долю от общего времени. Эта версия гораздо сложнее предыдущей, однако эта сложность окупается с лихвой благодаря отказу от использования strlen и strchr в isspam и замене sees % cum% cycles instructions calls function strncmp на memcmp, которая тратит меньше усилий и обработку каждого байта.

secs % cum% cycles instructions calls function
3.524 56.9 56.9 880890000 1027590000 46180000 memcmp
2.662 43.0 100.0 665550000 902920000 10000 isspam
0.001 0.0 100.0 140304 106043 652 strlen
0.000 0.0 100.0 100025 100028 1 main

Весьма поучительно будет потратить некоторое время на сравнение счетчиков циклов и количества вызовов различных функций в двух профилях. Отметьте, что количество вызовов strlen упало от нескольких миллионов до 652, а strncmp и memcmp вызываются одинаковое количество раз. Обратите внимание и на то, что isspam, которая сейчас взяла на себя и функцию strchr, умудряется обойтись гораздо меньшим количеством циклов благодаря тому, что она проверяет на каждом шаге только нужные образцы. Изучение чисел может раскрыть и многие другие детали хода выполнения программы.

"Горячая точка" нередко может быть уничтожена или, по крайней мере, существенно "охлаждена" гораздо более простыми способами, чем мы применили для спам-фильтра. Когда-то давным-давно профилирование Awk показало, что одна функция вызывается примерно миллион раз – в таком цикле:

? for (j ='i; j < MAXFLD; j++)
? clear(j);

Выполнение этого цикла, в котором поля очищались перед считыванием каждой новой строки ввода, занимало почти 50% от всего времени исполнения. Константа MAXFLD – максимальное количество полей в строке ввода – была равна 200. Однако в большинстве случаев использования Awk реальное количество полей не превышало двух-трех.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.