Оптимизация отчетов и обработок

From SunFlurry wiki
Jump to: navigation, search

Рабочая среда SunFlurry выполнена таким образом, чтобы скорость исполнения кода, запросов, формирования отчетов, изменения информации и пр. была оптимальной. Работа подобной системы, однако, является результатом сложного взаимодействия множества разнообразных частей, при этом система всегда работает с ограниченными ресурсами, часто экономия одного ресурса негативно сказывается на другой ресурс, поэтому невозможно достичь оптимизации по всем параметрам одновременно. Оптимизация, если она необходима, подбирается разработчиком исходя из задачи. Также возникают ситуации, когда приходится спрашивать у пользователя, каким образом ему необходимо выполнить ту или иную работу (к примеру, если какой-либо отчет может быть сформирован быстро, но при этом использовать много памяти при формировании, пользователь на машине с ограниченной памятью, может предпочесть более медленное формирование, которое экономней подходит к памяти, так как в ином случае, отчет не сможет сформироваться). При работе системы, можно выделить следующие параметры оптимизации (сортированные более или менее по степени их важности):

  • Гибкость и полнота настроек для пользователя, его возможность получить желаемый результат в требуемом виде. Предоставление более гибкого инструмента пользователю является важнейшей задачей при создании обработки. При выполнении работы отсутствие гибкости в настройках может заставить пользователя тратить дополнительное время на обработку результата.
  • Время выполнения работы является важным фактором при выполнении обработки.
  • Расход системной памяти локальной машины при работе может быть важным фактором, даже если используется 64-битный клиент, если системной памяти недостаточно. Для 32-битных клиентов количество выделяемой памяти ограничено архитектурой и часто не может превышать 2Гб (с учетом пространства, резервируемого операционной системой), поэтому для 32-битной архитектуры экономия памяти является особенно важной задачей.
  • В случае, если клиент соединяется с сервером через сеть с высокой задержкой (к примеру, Интернет), чем меньше запросов будет отправлено на сервер, тем быстрее будет работать обработка, так как запросы внутри одного потока выполняются последовательно, то есть, пока текущий запрос не вернет ответ, новый не будет отослан на сервер. Длительные обработки создают десятки и сотни тысяч запросов на сервер (не обязательно к базе данных), такое количество запросов может сильно замедлять выполнение, если задержка между отсылкой запроса и получением ответа на него высока.
  • Нагрузка на процессор сервера во время работы. Машина, на которой находится сервер и СУБД обслуживает одновременно множество пользователей, и, если один из них использует большинство ресурсов процессора, это замедляет работу остальных.
  • Расход памяти на серверной машине или утилизация его жесткого диска во время работы. Иногда объемные запросы также расходуют большое количество памяти на сервере, это может увеличить нагрузку на его жесткие диски (так как новые запросы могут выполняться с использованием буфера на диске) и замедлит работу. Нужно заметить однако, что принцип буферизации информации СУБД минимизирует влияние больших запросов на расход памяти на сервере.
  • Сложность программного кода для понимания или модификации. Данный фактор нужно принимать во внимание для сложных обработок. Если исходных код их достаточно запутан и его тяжело понять, разработчик потратит большее время на его изменение и самые простые изменения могут внести в исходных код ошибки, исправить которые будет тяжело.
  • Длительность и сложность написания программного кода. Некоторые алгоритмы требуют больших усилий при написании исходного кода. Оптимизация исходного кода обычно увеличивает его объем и время написания.
  • Нагрузка на локальную сеть или канал Интернет. Может представлять определенный интерес при оптимизации, особенно, если система обслуживает http-запросы. Чем меньше информации передается по каналу в этом случае, тем ниже его загрузка и тем быстрее происходит передача.

В данной статье собраны только возможности системы, которые остаются на усмотрение разработчика, встроенные оптимизации системы, работающие по умолчанию, здесь не упоминаются. Эти функциональные возможности помещены в одну таблицу, в которой описано их влияние на различные параметры оптимизации.

Описание оптимизации Время выполнения Расход памяти Нагрузка на сервер Другое
Использование расширенных функций загрузки объектов, для их позиционирования без загрузки. Позволяют использование этих объектов для фильтров в запросах, а также в рабочих циклах совместно со сборщиком объектов и т.д. Оптимизация может использоваться как для ускорения работы, так и для оптимизации используемой памяти. Функции, используемые для загрузки объектов в этом режиме FindEx, LoadEx, SelectEx. Существенно уменьшается Существенно уменьшается Уменьшается Уменьшается также нагрузка на сеть (или канал), при небольшом усложнении кода.
Загрузка объектов базы данных в режиме заголовков или в режиме частичной загрузки. Позволяют использование этих объектов при выводе на экран, сортировке, в визуальных таблицах или списках, в запросах и т.д., когда все реквизиты объекта для выполнения работы не требуются. Оптимизация может использоваться как для ускорения загрузки, так и для уменьшения используемой памяти. Функции, используемые для загрузки объектов в этом режиме MassLoadObjects, FindEx, LoadEx, SelectEx. Существенно уменьшается Существенно уменьшается Несущественное влияние Уменьшается также нагрузка на сеть (или канал), при небольшом усложнении кода.
Функция MassLoadObjects используется для оптимизации скорости загрузки большого числа объектов базы данных, как при их обработке в цикле, так и перед визуальным выводом. Даже в режиме полной загрузки объектов, функция выполняется быстрее, чем последовательная загрузка множества объектов при обращении к их реквизитам. Кроме того, функция гарантирует всего один запрос к серверу (сервер может создать множество запросов к базе данных) на один вызов функции). Уменьшается Несущественное влияние Может значительно уменьшиться количество запросов на сервер (актуально при работе с сервером через Интернет), Незначительное усложнение кода.
Функции для работы с транзакциями BeginTransaction, CommitTransaction и RollbackTransaction при неверном использовании могут вызвать сильное замедление работы пользователей, однако, в СУБД типа SQLite, использование транзакции для нескольких операций записи одновременно может значительно увеличить скорость обработки. Транзакции рекомендуется использовать, если длительный процесс создает большое количество новых элементов справочников или документов, а также, если происходит множественное изменение элементов справочников или документов. Важно также понимать, что если транзакция будет очень длительной, работа других пользователей может быть замедлена, если она связана с изменением тех же справочников или тех же документов, которыми оперирует сама транзакция, поэтому рекомендуется фиксировать транзакцию и начинать ее снова после определенного количества изменений. Для СУБД типа MS SQL такой подход не является особенно выигрышным, но и не замедляет обработку. Существенно уменьшается (для некоторых СУБД) Уменьшается (особенно уменьшается нагрузка на жесткий диск сервера) Усложнение кода.
Строковая функция AppendStringToBufferedString используется для оптимизации создания длинной строки из множества более маленьких строк в рабочем цикле. Существенно уменьшается Незначительное усложнение кода.
Функции строк-массивов значений (JoinStringValues, SortStringValues и др.) могут быть использованы при разборе строк с разделителями, если необходимо сохранять изменения непосредственно в этих строках. Однако, если необходимо только получить массив из строки, но не сохранять его снова в строку, или при работе с элементами справочников, быстрее использовать списки (которые могут занимать чуть больше места в памяти). Существенно уменьшается Возможное упрощение кода.
Функции временной таблицы базы данных позволяют перенести обработку и хранение таблиц запросов во временные таблицы сервера (СУБД), тем самым исключая возможность переполнения памяти при очень больших запросах. После выполнения запроса, результат может быть получен с помощью выборки, которая очень хорошо взаимодействует со сборщиком объектов. У временных таблиц есть минусы: увеличение нагрузки на сервер, изменение концепции запроса, усложнение кода, замедление (в некоторых случаях, ускорение). Существенно уменьшается или увеличивается в зависимости от типа работы. Существенно уменьшается, концепция позволяет обрабатывать таблицы запросов произвольной величины. Незначительно увеличивается расход памяти, может увеличиться нагрузка на жесткие диски. Применимо только к СУБД, сам процесс сервера не страдает. Усложнение написания кода, усложнение кода для понимания.
Функции блокировки обновления графических элементов формы при выполнении большого количества изменений (к примеру, Tab.Lock, List.Lock, Table.Lock или Picture.Lock) позволяют существенно ускорить изменения в графических элементах, так как каждое изменение не обновляет элемент на экране, он обновляется после выполнения всех изменений. Существенно уменьшается Незначительное усложнение кода.
Использование сортированных списков и таблиц для быстрого нахождения значений в них (см., к примеру, функции List.Find, Tab.Find, Tab.AddLineSorted и др.) позволяет существенно увеличить скорость поиска в таблицах и списках. Особенно удобно использовать такие функции в цикле с поиском и добавлением. Существенно уменьшается Незначительное усложнение кода (при написании кода, нужно понимать, что таблица или список становятся сортированными).
Использование особого режима поиска (1) вхождения элементов в список с папками (см., к примеру, функции List.Contains, DB.Contains, DB.IsPartOf и др.) в определенных случаях (большое количество папок и элементов входит в список и его подпапки) позволяет существенно увеличить скорость первого вызова функции проверки для определенных СУБД (типа SQLite). Уменьшается или существенно уменьшается Незначительно уменьшается или Увеличивается (в случае справочников с очень большим количеством папок) Незначительно уменьшается
При работе с входящими TCP/IP соединениями, удобно использовать линейную функцию принятия соединения (см. IPConnection.ListenEx). Это позволяет сделать код более понятным (так как он будет располагаться в одном фрагменте, а не в двух). Упрощение кода
Функции сборщика объектов позволяют существенно уменьшить количество новых загружаемых объектов в любом цикле обработки, где присутствуют незагруженные или частично загруженные объекты подобных видов, если они могут часто повторяться. При этом ускоряется работа, уменьшается расход памяти и уменьшается нагрузка на сервер. Существенно уменьшается (в зависимости от количества повторяемых объектов в обработке) Существенно уменьшается (в зависимости от количества повторяемых объектов в обработке) Уменьшается (в зависимости от количества повторяемых объектов в обработке) Незначительное усложнение кода.
Так как запросы работают с таблицами в формате системы, для более удобного получения доступа к ним и их изменения, при работе с большими базами данных, может возникнуть ситуация, когда таблица запроса занимает слишком много памяти. Для уменьшения количества памяти в режиме запросов, существует ряд оптимизаций, которые можно использовать в запросах. Все эти оптимизации перечислены на странице статьи Объект запрос базы данных в разделе Замечания по оптимизации выполнения запроса. Уменьшается или существенно уменьшается Незначительное усложнение кода.
Функции Compile, LoadFunctionFromBuffer, SaveFunctionToBuffer позволяют избежать многократной компиляции исходных текстов, созданных вне Студии (макросов пользователей, драйверов для работы с устройствами и т.д.) и особенно выгодны, если исходный текст находится в критическом блоке исполнения, где важна скорость исполнения. Компилированные тексты можно также сохранять на диске, чтобы создать файлы кэша, для того, чтобы избежать повторной компиляции вообще. Уменьшается или существенно уменьшается (по сравнению с временем множественного выполнения Exec с исходным текстом) Незначительное усложнение кода.
Функции LoadFileNames и LoadFiles позволяют уменьшить количество запросов к серверу, получая информацию о файлах или загружая содержимое файлов одним запросом. Таким образом ускоряется выполнение для клиентов, работающих через медленные подключения (к примеру, Интернет). Может значительно уменьшиться количество запросов на сервер (актуально при работе с сервером через Интернет), Незначительное усложнение кода.