
Чек-лист по оптимизации производительности клиентских приложений на платформе Progress OpenEdge
Эффективность функционирования информационной системы определяется как характеристиками программного обеспечения, так и параметрами аппаратного обеспечения, на котором оно выполняется. Границы между понятиями «производительность программного обеспечения» и «производительность аппаратного обеспечения» являются достаточно условными.
Производительность программного обеспечения зависит от качества исходного кода, методов программирования, архитектуры базы данных и алгоритмов обработки данных.
Производительность аппаратного обеспечения определяется конструкцией программного продукта, характеристиками оборудования, операционной системы и сетевой инфраструктуры.
Для достижения максимальной производительности информационной системы необходимо провести комплексный анализ её компонентов, включая программное обеспечение, аппаратные ресурсы, управление памятью, дисковыми подсистемами, центральным процессором и сетевыми взаимодействиями. Оптимизация производительности достигается за счёт более эффективного распределения вычислительных ресурсов, оптимизации программного кода и улучшения структуры базы данных.
В рамках повышения производительности программного обеспечения рекомендуется обратить внимание на следующие аспекты:
- Индексирование данных
Необходимо тщательно выбирать структуру индексов и использовать критерии отбора (условие WHERE) таким образом, чтобы максимально задействовать индексы. При использовании оператора MATCHES индекс не применяется, а выборка записей с пропуском первого поля в многосоставном индексе также не позволяет использовать индекс. Например, при запросе записей с средним именем «Мэри», если индекс включает поля last_name, first_name и middle_name, система должна будет последовательно просмотреть все записи, что существенно снизит производительность. Для анализа кода рекомендуется использовать компиляцию кода с COMPILE с LISTING и COMPILE с XREF.
- Оптимизация объёма транзакций
Необходимо минимизировать размер транзакций для снижения нагрузки на файл BI и предотвращения блокировки записей в многопользовательских приложениях на длительное время.
- Минимизация ввода-вывода
Взаимодействие с периферийными устройствами является ресурсоёмким процессом, поэтому рекомендуется минимизировать количество операций ввода-вывода. Например, при отображении счётчика в процессе можно обновлять его значение каждые 100 записей, вместо того чтобы делать это на каждой итерации цикла.
- Использование атрибута NO–UNDO для переменных программы
Переменные программы записываются в локальный файл перед созданием образа (.lbi) когда системе необходимо отслеживать их промежуточные значения. Использование атрибута NO-UNOD позволяет избежать этой дополнительной записи.
- Минимизация рекурсии
Рекурсивные вызовы функций могут существенно увеличить нагрузку на центральный процессор из-за управления стеком вызовов. Рекомендуется избегать рекурсии в пользу итеративных алгоритмов.
- Оптимизация системных вызовов
Вызовы операционной системы могут привести к дополнительным накладным расходам на управление памятью и другими ресурсами. В случаях, когда существует возможность выполнить требуемую операцию без обращения к операционной системе, следует использовать эту альтернативу.
- Оптимизация работы с фреймами
Использование директив HIDE и VIEW позволяет минимизировать количество активных фреймов, что снижает нагрузку на центральный процессор.
- Ограничение использования глобальных переменных
Глобальные переменные увеличивают размер исполняемого кода программы, что может негативно сказаться на производительности. Рекомендуется объявлять глобальные переменные только там, где это действительно необходимо, и избегать их избыточного использования.
Управление памятью в информационных системах может быть оптимизировано путем настройки параметров запуска операционной системы и/или управления памятью. Рекомендуется последовательно рассмотреть каждый из следующих параметров запуска:
- Размер каталога (-D)
При установке значения параметра -D ниже оптимального уровня возникают нежелательные процессы перекомпиляции, а также повторное открытие и перечитывание файлов R-кода. Увеличение значения -D способствует сохранению часто используемых R-файлов в файле .srt, что сокращает время на операции поиска, перемещения и открытия файлов.
- Максимальный объем памяти (-mmax)
Для выполнения сложных процедур или при использовании глубоко вложенных вызовов процедур рекомендуется увеличить начальный размер буфера выполнения с помощью параметра -mmax. Это позволяет уменьшить количество операций ввода-вывода на диске, связанных с переносом сегментов данных в файл сортировки.
- Размер локального буфера (-l)
Увеличение размера локального буфера незначительно повышает производительность системы за счет снижения частоты освобождения памяти Progress.
- Размер стека (-s)
Параметр -s определяет размер стека, который представляет собой внутреннюю область памяти, используемую программными модулями Progress. Этот параметр предотвращает ошибки переполнения стека, обычно возникающие при загрузке определений данных для больших таблиц или при выполнении рекурсивных программ. Размер стека указывается в единицах 1 КБ.
- Запуск быстрой сортировки (-TB) и номер слияния быстрой сортировки (-TM)
Для ускорения сортировки неиндексированных полей, таких как сортировка во временных таблицах, применяются параметры -TB и -TM.
- Параметр -TB управляет размером блоков, выделяемых Progress для сортировки.
- Параметр -TM определяет количество блоков, которые могут быть объединены за один проход.
Эти параметры особенно важны при построении индекса с использованием утилиты PROUTIL.
Эффективное управление дисковыми ресурсами и оптимизация сетевого взаимодействия играет ключевую роль в обеспечении производительности вычислительных систем. Одним из подходов к оптимизации является распределение задач ввода-вывода между различными устройствами хранения данных. Это позволяет более рационально использовать вычислительные мощности и сократить время отклика системы. Рассмотрим основные подходы и параметры конфигурации, направленные на улучшение производительности дисковых операций и сетевых взаимодействий.
Управление дисковыми ресурсами:
- Опция быстрого запроса (-q)
Данная опция позволяет избежать повторного поиска пути к файлам (PROPATH) при каждом выполнении процедур с использованием оператора RUN. Это особенно полезно в условиях, когда приложение уже запущено и структура файлов исходного кода (.p) остаётся стабильной.
- Использование временного каталога (-T)
Для оптимизации дискового пространства и снижения конкуренции за ресурсы рекомендуется выделять отдельный каталог для временных файлов. Это позволяет изолировать временные файлы от основных данных (.db, AI, BI) и при использовании независимых дисков обеспечить параллельный ввод-вывод, что значительно повышает производительность системы.
- Буферизация временных таблиц (-Bt)
Временные таблицы, создаваемые в процессе выполнения запросов, могут быть размещены в памяти с использованием буфера, указанного параметром -Bt. Размер буфера по умолчанию (512 КБ) может быть недостаточным для приложений, интенсивно использующих временные таблицы. В таких случаях рекомендуется увеличить размер буфера с помощью параметра -tmpbsize.
Оптимизация сетевого взаимодействия
- Настройка размера буфера сообщений (-Mm)
В случае использования крупных записей в базе данных рекомендуется увеличить размер буфера сообщений, чтобы минимизировать фрагментацию данных и улучшить производительность сети. Однако при работе с сетями, где предпочтительны небольшие сообщения, можно уменьшить размер буфера, что приведёт к фрагментации более крупных записей.
– До версии OpenEdge 11.6: параметр -Mm должен был быть одинаковым для клиента и сервера. В случае использования -Mm в качестве параметра запуска базы данных, все клиент-серверные подключения к этой базе данных должны были иметь одинаковый размер буфера сообщений.
– Начиная с OpenEdge 11.6: необходимость указания -Mm на стороне клиента отпала. Если значение -Mm указано на клиенте, оно используется только в качестве рекомендации. Основной размер буфера определяется параметром сервера.
- Параметры предварительной выборки (-prefetchDelay, -prefetchFactor, -prefetchNumRecs, -prefetchPriority, -Nmsgwait)
Эти параметры, введённые в OpenEdge 10.2B06 и 11.1.0, позволяют оптимизировать процесс предварительной выборки данных, что снижает нагрузку на сеть при крупномасштабном развёртывании. Они позволяют настроить поведение системы при упаковке сообщений для запросов, а также частоту вызовов системного вызова poll().
- Использование файла кэша схемы (-cache)
При работе через глобальные сети (WAN) файл кэша схемы может значительно сократить время подключения клиентов к базе данных. Progress сохраняет кэш схемы в виде двоичного файла на локальном диске, что позволяет клиентам считывать схему непосредственно из кэша. Этот параметр рекомендуется использовать при большом количестве одновременных подключений.
- Оптимизация расположения r-кода на диске
Чтение r-кода с сетевых дисков, особенно при отсутствии сопоставления ссылок на диски с их буквами, может привести к снижению производительности из-за необходимости первоначального чтения каждого файла r-кода. Рекомендуется хранить r-код локально или, по крайней мере, в библиотеках процедур.
Улучшения в OpenEdge 12
С выходом версии OpenEdge 12 были внесены значительные улучшения в поддержку многопоточности и объединений запросов на стороне сервера. Эти изменения направлены на повышение производительности и эффективности работы с большими объёмами данных по сети.
Инструменты и методы для диагностики проблем производительности в OpenEdge
В OpenEdge начиная с версии 10.x для анализа производительности применяются различные инструменты и методы. Основные из них включают:
- Использование системного дескриптора LOG-MANAGER
LOG-MANAGER (параметр запуска -clientlog) предоставляет возможность настройки журналирования для выявления проблемных участков кода. Доступны различные уровни журналирования.
– 4GLTRACE (уровень 3): Отслеживает выполнение операторов RUN, вызовов классов и методов. Отображает параметры и возвращаемые значения. Позволяет определить время выполнения операций, что помогает локализовать узкие места в коде.
– FILEID: Используется для анализа взаимодействия приложения с файловой системой. Отслеживает операции открытия, закрытия и блокировки файлов. Выявление длительных операций с файлами может указывать на узкие места в обработке данных.
– QRYINFO: Предоставляет детализированную информацию о запросах, включая эффективность их выполнения. Позволяет выявлять запросы с неоптимальным использованием индексов, что приводит к избыточным операциям чтения из базы данных.
Признаки неоптимального использования индексов включают:
- Значительное превышение количества операций чтения из базы данных над количеством записей, полученных с сервера.
- Использование только части компонентов запроса, что требует дополнительного чтения данных для выполнения полного запроса (WHOLE-INDEX).
Для устранения подобных проблем рекомендуется создание новых индексов, включающих необходимые поля.
- Системный дескриптор PROFILER
PROFILER (параметр запуска -profile) регистрирует время выполнения каждой строки кода в ABL-программах. Полученные данные можно анализировать с помощью Developer Studio для OpenEdge или в устаревшем интерфейсе на основе ABL, доступном здесь.
Профилирование позволяет выявить наиболее ресурсоемкие участки кода, что способствует оптимизации производительности приложений.
Для более глубокого понимания возможностей PROFILER и его интеграции с инструментами разработки рекомендуется ознакомиться с дополнительными статьями:
- Как использовать профилировщик в OpenEdge Architect / Developer Studio для OpenEdge?
- Атрибуты и методы объекта PROFILER
Эти инструменты и методы позволяют проводить детальный анализ производительности приложений на базе OpenEdge, выявлять узкие места и оптимизировать код для повышения эффективности работы системы.