Страница 1 из 3
Возращаясь к вопросу о прозводительности.
Добавлено: 21 апр 2010, 09:40
Леонид
Не пойму, что не так. Доделал один из отчётов. Да, он сложный, да, он использует DockStyle = Left, CanGrow и GrowToHeight во всех текстовых полях, т.к. это действительно необходимо.
Но в любом случае, запрос Oracle выполняется 2-4 сек., а отчёт рисуется 25-30 сек., и в нём при этом ровно 5 страниц. Это ненормально!
Отчёт с xml-файлом и схемой в приложении поста, чтобы можно было посмотреть. Но это нереально медленно, т.к. в старом проекте на Дельфе под FastReport'ом 3-м тоже самое рисуется несколько секунд. А когда я делают выборку по филиалам, то select выполяется около 16 секунд, а рисуется 16 минут, правда там и страниц намного больше, несколько сотен. Но это в любом случае неприемлемо. Т.к. это время на Intel Quad 2 Q6600 2.4 Ghz, а что же будет на Celeron'ах???
Я пробовал следовать всем Вашим рекомендациям, а именно, убрал у всех бендов и текстовых полей CanGrow и пр., убрал DockStyle (поставил None) и прочее, но не помогло.
Возращаясь к вопросу о прозводительности.
Добавлено: 23 апр 2010, 07:36
Леонид
Ребята, ну что, есть какие-нибудь идеи или соображения по поводу топика?
Возращаясь к вопросу о прозводительности.
Добавлено: 23 апр 2010, 11:12
Ivan
Здравствуйте.
С проблемой разобрались.
Пожалуйста у текстбокса Text49 установите свойство TextFormat в General и свойство HideZeros в false.
В этом поле у вас выводится только текст, а при обработке свойства HideZeros производится парсинг поля и получаются exceptions, которые и тормозят.
Также мы подправили код метода, чтобы в будущем такая ситуация не возникала.
Спасибо.
Возращаясь к вопросу о прозводительности.
Добавлено: 23 апр 2010, 12:20
Леонид
Сделал всё, как Вы сказали, но увы, это не помогло. Отчёт (5 страниц) по прежнему рисуется 26 сек. Даже не знаю, что делать.
Возращаясь к вопросу о прозводительности.
Добавлено: 24 апр 2010, 20:53
Ivan
Здравствуйте.
Если причина низкой скорости работы связана с exceptions, вы можете посмотреть, в каком именно текстбоксе возникает ошибка.
Для этого запустите ваш отчет в дизайнере, и после того как он отобразится в превью, на закладке Messages в нижней части дизайнера будет список всех ошибок, которые возникли при построении отчета.
Спасибо.
Возращаясь к вопросу о прозводительности.
Добавлено: 25 апр 2010, 06:38
Леонид
Ivan писал(а):Здравствуйте.
Если причина низкой скорости работы связана с exceptions, вы можете посмотреть, в каком именно текстбоксе возникает ошибка.
Для этого запустите ваш отчет в дизайнере, и после того как он отобразится в превью, на закладке Messages в нижней части дизайнера будет список всех ошибок, которые возникли при построении отчета.
Видимо не связано с ошибками, т.к. я запустил дизайнер после отрисовки отчёта, в Messages ничего не написано, т.е. ошибок нет, а скорость отрисовки всё тех же 5 страниц крайне низкая - 25-27 сек.
Вопрос, а у Вас рисуется за какое время? В любом случае проблема не решена.
Возращаясь к вопросу о прозводительности.
Добавлено: 26 апр 2010, 06:25
Леонид
Сегодня "игрался" с отчётом в целях отыскать проблему производительности. Нашёл - это ячейки, в которых присутствуют конструкции вида:
{IIF(Sum(DataBand1, qrMain.SALES_PLAN) <= 0, 0, Div(Totals.Sum(DataBand1, qrMain.AMOUNT_OUT) - Totals.Sum(DataBand1, qrMain.AMOUNT_RET), Totals.Sum(DataBand1, qrMain.SALES_PLAN)) * 100)}. То есть, вероятно, проблема возникает из-за медленного суммирования ячеек.
Итог экспериментов таков. Из ячеек в группах с заголовками (последние справа): "% плана продаж", "% плана оплат", "% отгр. к пред. году", "Обор." убрал весь интерпертируемый код вообще.
Результат -
5 страниц рисуется
3-4 сек., вместо
25-27 сек.
А те 63 страницы, которые рисовались
16 минут стали рисоваться за
10-11 сек. Это шок, ребята!!!
Иными словами, проблема оказалась даже не в HideZeroes, т.к. вместе с тем, что я убрал из всех этих четырёх ячеек код (во всех группах), но оставил во всех текстовых полях в Header'е HideZeroes у ВСЕХ полей - никаких exception отчёт не выдавал и время отрисовки сильно не изменилось.
Прошу Вас разобраться почему так медленно происходит суммирование в ячейках с группами.
Возращаясь к вопросу о прозводительности.
Добавлено: 26 апр 2010, 18:33
Ivan
Здравствуйте.
Разъясняем ситуацию.
Конструкция типа Totals.Sum(DataBand, Field) вычисляет сумму по указанному полю для всех записей датабэнда. При этом датабэнд прокручивается полностью для каждого вызова функции, что и создает приличные затраты времени.
В вашем случае используется одиннадцать групфутеров, на каждом по четыре текстбокса с выражениями, в каждом выражении по 3-4 вызова функции. Итого получается больше сотни вызовов функции, соответственно датабэнд прокручивается полностью больше сотни раз.
Но всё это легко оптимизируется. Изучив ваш отчет видим, что в каждом из указанных столбцов выражения одинаковые. Соответственно, мы выносим все вычисления сумм за пределы цикла. Для этого делаем следующее:
- создаем в словаре четыре переменных Func1, Func2, Func3, Func4 типа decimal.
- в событии BeforePrint компонента ReportTitle пишем следующий код для вычисления сумм:
Код: Выделить всё
Func1 = Div(Div(Totals.Sum(DataBand1, qrMain.DEBT_START) + Totals.Sum(DataBand1, qrMain.DEBT_END), 2) * Var_k, Totals.Sum(DataBand1, qrMain.AMOUNT_PAY));
Func2 = Div(Totals.Sum(DataBand1, qrMain.AMOUNT_OUT) - Totals.Sum(DataBand1, qrMain.AMOUNT_RET), Totals.Sum(DataBand1, qrMain.SALES_PLAN)) * 100;
Func3 = Div(Totals.Sum(DataBand1, qrMain.AMOUNT_PAY), Totals.Sum(DataBand1, qrMain.PAYMENTS_PLAN)) * 100;
Func4 = Div((Totals.Sum(DataBand1, qrMain.AMOUNT_OUT) - Totals.Sum(DataBand1, qrMain.AMOUNT_RET)), (Totals.Sum(DataBand1, qrMain.AMOUNT_PREV_OUT) - Totals.Sum(DataBand1, qrMain.AMOUNT_PREV_RET)) * 100);
- во всех местах вызова функций заменяем выражения на соответствующие переменные, например вместо кода
Код: Выделить всё
{IIF(Sum(DataBand1, qrMain.SALES_PLAN) <= 0, 0, Div(Totals.Sum(DataBand1, qrMain.AMOUNT_OUT) - Totals.Sum(DataBand1, qrMain.AMOUNT_RET), Totals.Sum(DataBand1, qrMain.SALES_PLAN)) * 100)}
пишем код
Код: Выделить всё
{IIF(Sum(DataBand1, qrMain.SALES_PLAN) <= 0, 0, Func4}
Сравниваем скорость построения отчета. На нашей тестовой машине первоначальный отчет строился 35 секунд, после оптимизации полученный отчет строится за 5 секунд.
Пример оптимизированного отчета прикреплен к топику.
Спасибо.
Возращаясь к вопросу о прозводительности.
Добавлено: 27 апр 2010, 06:31
Леонид
Сделал всё, как Вы написали, всё заработало.
Теперь то, что рисовалось 16 минут рендериться за 33 секунды. :biggrin:
Ещё я изменил конструкцию вида {IIF(Sum(DataBand1, qrMain.SALES_PLAN) <= 0, 0, Func4} на {IIF(SaleSimpleSum <= 0, 0, Func4}, а SaleSimpleSum объявил как decimal и рассчитал (Sum(DataBand1, qrMain.SALES_PLAN)) в BeforePrint в ReportTitle. И так во всех четырёх полях всех GroupFooter'ов. В итоге, 16 минут (63 страницы) рисуются за 15 секунд, что впечатляет.
Правда после рендеринга сам вывод на экран длится порядка 15 секунд, т.е. в итоге суммарно получается 30-35 секунд. Это круто в любом случае. Вопрос по поводу вывода на экран отрендеренного отчёта в MDI это уже тема другой ветки.
Благодарю за помощь, Вы очень помогли, т.к. это один из самых важных отчётов. :feelgood:
P.S. Ещё вопрос. А нельзя ли сделать в будущих релизах анализ таких (одинаковых) кусков кода, где присутствуют суммирования по всему DataTable, чтобы не создавать кучу переменных, а сам генератор отчётов подставлял в нужные места вместо кода Sum(DataBand1, qrMain.SALES_PLAN) какую-нибудь уже посчитанную переменную?
Возращаясь к вопросу о прозводительности.
Добавлено: 27 апр 2010, 13:42
Леонид
Сейчас внимательнее посмотрел на отчёт и понял, что считается-то неправильно, т.к. значение должно считаться для каждой группы, а оно получается считается один раз для всего DataTable, а потом значение просто подставляется для каждой группы. Это неверно.
Как же быть??? :oho:
Может быть на другое событие вешать пересчёт переменных Func1, Func2 и т.д.?