Возращаясь к вопросу о прозводительности.
Возращаясь к вопросу о прозводительности.
Не пойму, что не так. Доделал один из отчётов. Да, он сложный, да, он использует 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) и прочее, но не помогло.
Но в любом случае, запрос Oracle выполняется 2-4 сек., а отчёт рисуется 25-30 сек., и в нём при этом ровно 5 страниц. Это ненормально!
Отчёт с xml-файлом и схемой в приложении поста, чтобы можно было посмотреть. Но это нереально медленно, т.к. в старом проекте на Дельфе под FastReport'ом 3-м тоже самое рисуется несколько секунд. А когда я делают выборку по филиалам, то select выполяется около 16 секунд, а рисуется 16 минут, правда там и страниц намного больше, несколько сотен. Но это в любом случае неприемлемо. Т.к. это время на Intel Quad 2 Q6600 2.4 Ghz, а что же будет на Celeron'ах???
Я пробовал следовать всем Вашим рекомендациям, а именно, убрал у всех бендов и текстовых полей CanGrow и пр., убрал DockStyle (поставил None) и прочее, но не помогло.
- Вложения
-
- slow_report.zip
- (36.85 КБ) 238 скачиваний
Возращаясь к вопросу о прозводительности.
Ребята, ну что, есть какие-нибудь идеи или соображения по поводу топика?
Возращаясь к вопросу о прозводительности.
Здравствуйте.
С проблемой разобрались.
Пожалуйста у текстбокса Text49 установите свойство TextFormat в General и свойство HideZeros в false.
В этом поле у вас выводится только текст, а при обработке свойства HideZeros производится парсинг поля и получаются exceptions, которые и тормозят.
Также мы подправили код метода, чтобы в будущем такая ситуация не возникала.
Спасибо.
С проблемой разобрались.
Пожалуйста у текстбокса Text49 установите свойство TextFormat в General и свойство HideZeros в false.
В этом поле у вас выводится только текст, а при обработке свойства HideZeros производится парсинг поля и получаются exceptions, которые и тормозят.
Также мы подправили код метода, чтобы в будущем такая ситуация не возникала.
Спасибо.
Возращаясь к вопросу о прозводительности.
Сделал всё, как Вы сказали, но увы, это не помогло. Отчёт (5 страниц) по прежнему рисуется 26 сек. Даже не знаю, что делать.
Возращаясь к вопросу о прозводительности.
Здравствуйте.
Если причина низкой скорости работы связана с exceptions, вы можете посмотреть, в каком именно текстбоксе возникает ошибка.
Для этого запустите ваш отчет в дизайнере, и после того как он отобразится в превью, на закладке Messages в нижней части дизайнера будет список всех ошибок, которые возникли при построении отчета.
Спасибо.
Если причина низкой скорости работы связана с exceptions, вы можете посмотреть, в каком именно текстбоксе возникает ошибка.
Для этого запустите ваш отчет в дизайнере, и после того как он отобразится в превью, на закладке Messages в нижней части дизайнера будет список всех ошибок, которые возникли при построении отчета.
Спасибо.
Возращаясь к вопросу о прозводительности.
Видимо не связано с ошибками, т.к. я запустил дизайнер после отрисовки отчёта, в Messages ничего не написано, т.е. ошибок нет, а скорость отрисовки всё тех же 5 страниц крайне низкая - 25-27 сек.Ivan писал(а):Здравствуйте.
Если причина низкой скорости работы связана с exceptions, вы можете посмотреть, в каком именно текстбоксе возникает ошибка.
Для этого запустите ваш отчет в дизайнере, и после того как он отобразится в превью, на закладке Messages в нижней части дизайнера будет список всех ошибок, которые возникли при построении отчета.
Вопрос, а у Вас рисуется за какое время? В любом случае проблема не решена.
Возращаясь к вопросу о прозводительности.
Сегодня "игрался" с отчётом в целях отыскать проблему производительности. Нашёл - это ячейки, в которых присутствуют конструкции вида: {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 отчёт не выдавал и время отрисовки сильно не изменилось.
Прошу Вас разобраться почему так медленно происходит суммирование в ячейках с группами.
Итог экспериментов таков. Из ячеек в группах с заголовками (последние справа): "% плана продаж", "% плана оплат", "% отгр. к пред. году", "Обор." убрал весь интерпертируемый код вообще.
Результат - 5 страниц рисуется 3-4 сек., вместо 25-27 сек.
А те 63 страницы, которые рисовались 16 минут стали рисоваться за 10-11 сек. Это шок, ребята!!!
Иными словами, проблема оказалась даже не в HideZeroes, т.к. вместе с тем, что я убрал из всех этих четырёх ячеек код (во всех группах), но оставил во всех текстовых полях в Header'е HideZeroes у ВСЕХ полей - никаких exception отчёт не выдавал и время отрисовки сильно не изменилось.
Прошу Вас разобраться почему так медленно происходит суммирование в ячейках с группами.
- Вложения
-
- sum_trouble.png (19 КБ) 3562 просмотра
Возращаясь к вопросу о прозводительности.
Здравствуйте.
Разъясняем ситуацию.
Конструкция типа Totals.Sum(DataBand, Field) вычисляет сумму по указанному полю для всех записей датабэнда. При этом датабэнд прокручивается полностью для каждого вызова функции, что и создает приличные затраты времени.
В вашем случае используется одиннадцать групфутеров, на каждом по четыре текстбокса с выражениями, в каждом выражении по 3-4 вызова функции. Итого получается больше сотни вызовов функции, соответственно датабэнд прокручивается полностью больше сотни раз.
Но всё это легко оптимизируется. Изучив ваш отчет видим, что в каждом из указанных столбцов выражения одинаковые. Соответственно, мы выносим все вычисления сумм за пределы цикла. Для этого делаем следующее:
- создаем в словаре четыре переменных Func1, Func2, Func3, Func4 типа decimal.
- в событии BeforePrint компонента ReportTitle пишем следующий код для вычисления сумм:
- во всех местах вызова функций заменяем выражения на соответствующие переменные, например вместо кода
пишем код
Сравниваем скорость построения отчета. На нашей тестовой машине первоначальный отчет строился 35 секунд, после оптимизации полученный отчет строится за 5 секунд.
Пример оптимизированного отчета прикреплен к топику.
Спасибо.
Разъясняем ситуацию.
Конструкция типа 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}
Пример оптимизированного отчета прикреплен к топику.
Спасибо.
- Вложения
-
[Расширение было запрещено, вложение больше недоступно.]
Возращаясь к вопросу о прозводительности.
Сделал всё, как Вы написали, всё заработало.
Теперь то, что рисовалось 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) какую-нибудь уже посчитанную переменную?
Теперь то, что рисовалось 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) какую-нибудь уже посчитанную переменную?
Возращаясь к вопросу о прозводительности.
Сейчас внимательнее посмотрел на отчёт и понял, что считается-то неправильно, т.к. значение должно считаться для каждой группы, а оно получается считается один раз для всего DataTable, а потом значение просто подставляется для каждой группы. Это неверно.
Как же быть??? :oho:
Может быть на другое событие вешать пересчёт переменных Func1, Func2 и т.д.?
Как же быть??? :oho:
Может быть на другое событие вешать пересчёт переменных Func1, Func2 и т.д.?
- Вложения
-
- groupfooter_sum.png (11.42 КБ) 3540 просмотров