Профилировщик Profiler
Профилировщики производительности является распространенными и полезными инструментами для разработчиков программного обеспечения. Вкратце, профилировщик обеспечивает «профиль» исполнения конкретной программы. Профилировщик обычно обеспечивает построение дерева вызовов и тайминг исполнения; Эта информация позволяет определить, какие части программы выполняются дольше всего.
Progress Software включает профилировщик Profiler в комплект поставки OpenEdge (каталог /samples/profiler1.1 на диске с документацией), но на условиях «Unsupported Free Software».
Функционально профилировщик состоит из двух частей. Во-первых, это сама по себе возможность профилирования, встроенная в клиент OpenEdge, которая создает и выводит необходимую информацию. И во-вторых, инструмент для импорта, интерпретации и просмотра информации профиля. Возможность профилирования впервые была включена как не документированная (и не поддерживаемая) функция в версии 8.2A; в версии 9.0b эта функция была документирована и включена в поддержку. Программа анализа не поддерживается Progress Software и включена в пакет в виде исходного кода «как есть».
Заметим, что для версии 10.2B профилировщик был расширен. Встроенная часть (runtime profiler) теперь генерирует четыре новые секции:
- Operators Section
- Module Details Section
- Session watermarks section
- Parameter and Database information section
Для просмотра конечным пользователем указанных выше четырех секций, средство просмотра профилировщика также было расширено. Предыдущая версия профилировщика по-прежнему доступна в каталоге /samples/profiler.
Средство просмотра Profiler Viewer работает только под Windows. Для установки его нужно запустить программу установки “OpenedgeProfilerSetup.msi”. Или можно просто скопировать каталог “profiler1.1” на диск и создать ярлык для скрипта “profilerviewer1.1.vbs”.
Замечание: в моем дистрибутиве в данном скрипте содержится ссылка на файл: “bin/profilerV.bat”, что приводит к ошибке скрипта в Windows (не удается найти указанный файл). Если это произойдет, просто поменяйте в скрипте “/” на “\”.
Для профилирования приложения ABL необходимо выполнить его с включенным в сессии режимом профилирования. После окончания сессии создается выходной файл, содержащий информацию о выполнявшемся коде и времени исполнения для каждой строки кода. Этот файл часто называют “profiling session”. Затем используется средство просмотра, которое импортирует этот файл в базу данных OpenEdge. В процессе импорта выполняется анализ полученных данных – и после этого profiling session доступна для просмотра.
Начиная с версии 9.0A доступен системный хэндлер PROFILER, который может быть использован для запуска и остановки профилировщика, для записи данных в выходной файл и управления другими параметрами профилирования.
Стандартно профилирование сессии включается с помощью параметра сессии –profile. Системный хэндлер PROFILER позволяет включать процесс профилирования и более точно управлять им из кода процедуры ABL.
Конфигурационный файл и хэндлер PROFILER.
Конфигурационный файл определяет, какую информацию следует собирать для последующего анализа (пример файла конфигурации, proconf.txt, включен в поставку). Функционально опции конфигурационного файла эквивалентны соответствующим атрибутам системного хэндлера PROFILER.
Указание стартового параметра –profile устанавливает значение атрибута PROFILER:ENABLED в True.
Конфигурационный файл может содержать следующие опции (символ “#” является признаком комментария, для каждой опции указан соответствующий атрибут хэндлера PROFILER):
COVERAGE | Initialize PROFILER:COVERAGE to True |
DESCRIPTION description | Initializes PROFILER:DESCRIPTION to description |
FILENAME filename | Initialize PROFILER:FILE-NAME to filename |
LISTINGS [directory] | Initialize PROFILER:LISTINGS to True and, if directory specified, PROFILER:DIRECTORY to directory |
PROFILING [yes | no] | Initialize the PROFILER:PROFILING to yes or no. If yes or no is not specified, the default is yes. If –PROFILING is not specified, the default is also yes |
STATISTICS | Initialize PROFILER:STATISTICS to True |
TRACE-FILTER patterns | Initialize PROFILER:TRACE-FILTER to patterns (if more than one token, it should be a quoted string) |
TRACING entries | Initialize PROFILER:TRACING to entries. This should be a quoted string |
Рассмотрим подробно атрибуты и методы хэндлера PROFILER:
- COVERAGE – Read/Write атрибут, тип Начальное значение No, если иное не установлено в конфигурационном файле при запуске сессии. Когда устанавливается в True, профилировщик начнет сохранять информацию об исполняемых строках и внутренних процедурах для каждой исполняемой внешней процедуры.
Заметим, что информация собирается только при первом выполнении внешней процедуры. Если PROFILER:COVERAGE = False при первом исполнении процедуры, установка его в True позже не приведет к сохранению информации о покрытии для этой процедуры.
- DESCRIPTION – Read/Write атрибут, тип Начальное значение “Unspecified”, если иное не установлено в конфигурационном файле при запуске сессии. Атрибут содержит название сессии профилирования, которое включается в выходной файл профилировщика.
- DIRECTORY – Read/Write атрибут, тип Если иное не установлено в конфигурационном файле при запуске сессии, начальное значение равно значению стартового параметра -T или, если -T не указано – текущему рабочему каталогу. Указывает каталог, в котором будут сохраняться автоматические листинги профилировщика. Не может быть установлен в неопределенное значение или в несуществующий каталог.
- ENABLED – Read/Write атрибут, тип Начальное значение False, если не указан стартовый параметр –profile. Активирует возможности профилирования.
Когда профилирование активируется в первый раз, выполняется регистрация всех активных процедур (persistent-процедур и процедур в стеке вызовов). Для каждой активной процедуры также генерируется листинг (если PROFILER:LISTINGS = True), и извлекается информация для анализа покрытия (если PROFILER:COVERAGE = True). Соответственно, имеет смысл установить PROFILER:LISTINGS (и/или PROFILER:COVERAGE) в True до установки PROFILER:ENABLED = True.
До тех пор, пока профилирование остается активированным, сессия ведет список данных профилирования, независимо от того, включено реально профилирование или нет. При деактивации профилирования (PROFILER:ENABLED = False), выполняется запись накопленной информации в выходной файл и очистка списка выполненных процедур.
- FILE-NAME – Read/Write атрибут, тип Начальное значение “profile.out”, если иное не установлено в конфигурационном файле при запуске сессии. Атрибут указывает имя выходного файла профилировщика. Не может быть установлен в неопределенное значение.
- LISTINGS – Read/Write атрибут, тип Начальное значение False, если иное не установлено в конфигурационном файле при запуске сессии. Установка этого атрибута в True требует от профилировщика автоматически генерировать листинги debug для профилируемого кода.
Заметим, что профилировщик генерирует листинг только при первом исполнении процедуры. Соответственно, если PROFILER:LISTINGS = False при первом исполнении процедуры, установка его в True позднее не приведет к генерации листинга для данной процедуры.
Профилировщик может только попытаться сгенерировать листинг debug, но не может этого гарантировать (например, если не все необходимые файлы доступны в PROPATH).
Можно повторить попытку генерации листингов, деактивировав и активировав заново средства профилирования (установив PROFILER:ENABLED = False, а затем снова в True).
- PROFILING – Read/Write атрибут, тип Начальное значение False, если иное не установлено в конфигурационном файле при запуске сессии. Установка этого атрибута включает и выключает процесс собственно профилирования. Если атрибут PROFILER:ENABLED = False, никаких действий не выполняется.
- STATISTICS – Read/Write атрибут, тип Начальное значение False, если иное не установлено в конфигурационном файле при запуске сессии. Если значение атрибута равно True, статистика сессии по вызовам процедур (см. выше) включается в выходной файл профилировщика.
- TRACE-FILTER – Read/Write атрибут, тип Начальное значение “”, если иное не установлено в конфигурационном файле при запуске сессии. Значение атрибута рассматривается как разделенный запятыми список выражений шаблонов (в формате функции MATCHES). Если имя процедуры соответствует одному из этих шаблонов, профилировщик будет генерировать тайминг для каждой исполняемой строки этой процедуры.
Если TRACE-FILTER = “”, то никакая процедура не может соответствовать этому условию, в этом случае профилироваться будут только элементы, заданные атрибутом PROFILER:TRACING. Если значение равно “*”, будут трассироваться все процедуры.
Сравнение шаблонов TRACE-FILTER не зависит от регистра (case insensitive).
В общем случае, профилировщик использует шаблоны TRACE-FILTER только при анализе собранных данных перед записью их в выходной файл (при выполнении PROFILER:WRITE-DATA() или по концу сессии). Так что, в большинстве случаев TRACE-FILTER может быть установлен непосредственно перед записью в выходной файл. Однако, профилировщик может выполнить частичный анализ на лету, если файл с сырыми собранными данными становится слишком большим. Соответственно, лучше установить TRACE-FILTER до выполнения любой процедуры, которая должна быть отфильтрована.
Избыточные элементы в списке PROFILER:TRACE-FILTER будут автоматически удалены.
- TRACING – Read/Write атрибут, тип Начальное значение равно “”. Так же, как и значение атрибута TRACE-FILTER, значение этого атрибута рассматривается как разделенный запятыми список. Отличие в том, что элементы этого списка идентифицируют конкретные исполняемые строки, для которых требуется детальный тайминг. Каждый элемент списка должен иметь формат procedure–name|line–number, где procedure–name – имя внешней процедуры (.p), а line–number – номер строки в листинге debug для оператора, который требуется трассировать.
Если атрибут TRACING = “”, то трассировка будет выполняться только для условий, заданных атрибутом PROFILER:TRACE-FILTER.
Так же, как шаблоны TRACE-FILTER, элементы списка TRACING используются профилировщиком только, когда он анализирует собранные сырые данные перед записью информации в выходной файл. Но при большом объеме данных может потребоваться анализ на лету, соответственно лучше установить необходимое значение атрибута TRACING заранее (до первого исполнения procedure–name|line–number).
Заметим, что если значение procedure–name соответствует одному из шаблонов в атрибуте TRACE-FILTER, то этот элемент списка TRACING является избыточным и не будет использован при анализе данных перед записью в выходной файл.
Избыточные элементы в списке PROFILER:TRACING будут автоматически удалены.
- USER–DATA(val AS Char) – Метод, принимающий один символьный (Character) параметр, возвращает значение типа Logical. Этот метод указывает профилировщику на необходимость записать значение его параметра в выходной файл профилировщика. Метод возвращает False, если запись выполнить не удалось (это возможно только если профилировщик не может открыть временный файл); в противном случае возвращается True. Если параметр имеет неопределенное значение, будет записан ?. В противном случае значение параметра будет заключено в кавычки, как при выполнении оператора ABL EXPORT. В дополнение к значению параметра будет также записано целое число, представляющее собой время в микросекундах с момента начала профилирования.
Назначение этого метода – позволить разработчику приложения собирать свою собственную информацию для профилирования (такую, как статистика базы данных, например) и записывать ее в выходной файл профилировщика. Любые пользовательские данные записываются в последнюю секцию выходного файла.
- WRITE–DATA() – Метод, не имеющий входных параметров и возвращающий значение типа Logical. Этот метод указывает профилировщику на необходимость выполнить анализ собранных на этот момент сырых данных и записать обработанные данные в выходной файл профилировщика. Метод возвращает False, если записать данные не удалось (это возможно либо из-за того, что нет никаких новых данных, либо невозможно открыть указанный выходной файл); в противном случае метод возвращает True.
Генерация выходных данных.
Укажите параметр запуска –profile в параметрах сессии, например:
prowin32 -profile proconf.txt -pf startup.pf -p main.p
Где ProWin32 – программа клиента ABL, proconf.txt – конфигурационный файл, задающий режимы профилирования, и main.p – стартовая процедура приложения, которое вы профилируете.
Или включите следующие операторы в точке приложения, откуда Вы хотите начать профилирование (это только пример, Вы можете использовать собственный набор установок профилирования, в соответствии с изложенной выше информацией):
PROFILER:ENABLED = YES. PROFILER:TRACE-FILTER = “*”. PROFILER:COVERAGE = YES. PROFILER:LISTINGS = YES. PROFILER:PROFILING = YES. /* We are profiling main.p below */ RUN main.p
Профилирование будет продолжаться до конца сессии, или до выполнения операторов, останавливающих профилирование, например:
. . . RUN main.p /* Stopping profiling after main.p */ PROFILER:WRITE-DATA(). PROFILER:PROFILING = NO. PROFILER:ENABLED = NO.
Для сокращения объема кода и облегчения читаемости можно рекомендовать написание соответствующих include-файлов, включающих и выключающих профилирование.
Для профилирования кода, выполняющегося распределённо, например на Application Server или WebSpeed Transaction Server, профилирование должно быть включено для соответствующих агентских сессий. Либо включено программно через хэндлер PROFILER, что намного удобнее.
Просмотр результатов профилирования с помощью Profiler Viewer Tool.
Для просмотра результатов выполните следующие действия:
- Запустите сессию Profiler Viewer (“profilerviewer1.1.vbs”)
- Нажмите кнопку “Add Session” для импорта выходных данных профилировщика.
- Введите имя файла с выходными данными и нажмите “OK”.
- Выберите режим “new extended profiler ver.” – для просмотра информации версии 10.2B.
- Нажмите кнопку “View Session”.
К сожалению, новый режим просмотра не показывает статистику по операторам, только по процедурам, правда намного удобнее, чем в старом режиме. К счастью, старый режим просмотра (“old profiler ver.”) тоже работает, и может быть использован для просмотра тайминга операторов.
Следует еще раз напомнить – профилировщик (точнее – средства просмотра) не является поддерживаемым продуктом, и задавать вопросы технической поддержке Progress Software смысла нет.
Вообще, использование профилировщика Profiler позволяет легко и удобно находить проблемные места в коде – после того как он установлен и все досадные проблемы устранены. К сожалению, для этого требуются некоторые затраты времени – хотя эти затраты вполне окупаются в дальнейшем, так что имеет смысл время найти.