На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила раздела:

  • Перед тем, как задать вопрос, желательно почитать документацию и воспользоваться поиском.
  • Когда задаёте вопрос, то обязательно указывайте платформу (7.7, 8.0, 8.1, 8.2, etc), причем желательно в заголовке. Если речь идёт о типовой конфигурации, то указывайте её название и релиз. Текущие версии можно посмотреть здесь.
  • Ещё раз напоминаем о необходимости соблюдать не только правила, но и законы. Уважайте авторские права.

Высказать своё мнение о модераторах раздела можно здесь: evGenius
Модераторы: evGenius
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Оптимизация. "Хороший стиль" написания под 1С, (заголовок изменен модератором)
    У меня как всегда вопросы к народу хитрые ;) Вот хочу узнать, может кто обладает информацией по поводу того какие методы быстрее и насколько выполняются? :)
    Наподобие того как в ассемблере например команда MOV это 4 такта...
    Сообщение отредактировано: evGenius -
    1=0
      Это парень не ООП, чтоб обсуждать подобные "параметры" :( , хотя есть определенные правила т.н.
      "хорошего стиля" - такая постановка вопроса более уместна, (в 1С не существует такого понятия как "рефакторинг" в прямом смысле) - поэтому чтобы писать хороший/эффективный "код" в 1С надо знать всего несколько правил:
      - особенность: если отчет (та же материальная ведомость в торговле) выполняется с условием отбора по группам товаров (особенно самого верхнего уровня), то для для каждой ниже лежащей (подчиненной) группы выполняется отдельный запрос. В итоге время построения отчета с условиями больше чем без оных!
      - Для уменьшения трафика сети и для разгруски сервера нужно использовать транзакции, в большенстве случаев очень сильно помогает, по крайней мере сеть сильно разгружается, и увеличивается общая производительность......
      - используй регистры! Пример: Если есть жесткая привязка документов оплаты и отгрузки к документу "Заявка" то проще сделать дополнительный регистр, в котором учитывать сумму заявки и суммы оплаты и отгрузки. Тогда тебе нужно будет просто получить итог данного регистра по конкретному документу на точку актуальности. Это будет быстрее. Но еще нужно будет создать примитивный документ корректировки данного регистра, поскольку если используются различные валюты оплаты то регистр может автоматически не закрываться
      - Обращаться к итогам в формах с табличной частью дольше, чем к реквизиту
      - получение остатков/оборотов по регистру на позицию проводимого документа - это существенно. И здесь, помимо _технически быстрого извлечения данных_ из таблиц, неважно в какой СУБД хранящихся, очень существенна _логическая_ организация данных. А, если я правильно понял, то разработчики БР именно этим и хлещутся - оптимизацией _хранения_ данных об остатках/оборотах.
      Т.е., я не хочу подменять 1С в умении вытаскивать данные из ею же организованных таблиц. Я хочу иметь лучщим образом организованные данные, чтобы результат получался быстрее по определению. На мой взгляд, только так и можно добиться увеличения производительности на порядки, а не в разы.
      - При выполнении запроса выполняется разделение его текста на две части: на серверную и на клиентскую. В серверную часть входят только краткие пути объявления внутренних переменных, в которых обращение идет только к полям регистров. Если в объявление переменной встречается длинный путь через точку, то он усекается до краткого, а остальная часть в дальнейшем обрабатывается на стороне клиента" И производительность запросов падает ниже, чем у штатного объекта "Запрос" в SQL версии :-)
      - используй прямые запросы (СКЛ)...
      - и последнее: На всех клиентах одна и та же ОС (один и тот же релиз), сет.катрочки одинаковые, драйвера одного релиза, плюс качественный монтаж кабеля и правильные сетевые настройки.
      Развлекайся! :)

      Добавлено в :
      Кстати для проверки всего вышесказанного и вообще на будущее рекомендую пользоваться утилиткой "замер производительности" из конфигуратора <_<
        Думаю, тут есть кое что интересное (в аттаче). Кстати, всё, что там сказано про SQL-версии, это правда.
        Да, и ежели внимательно отнестись к отборам в регистрах и БИ - тоже можно оочень всё ускорить.
        Прикреплённый файлПрикреплённый файлspeed_1C.zip (41.52 Кбайт, скачиваний: 1422)
        Q: Can I create anything unique in Delphi? A: Of course! <Ctrl + Shift + G>.. ;) ©Mch
          Тему закрепляю повыше, думаю, оно многим интересно будет.
          Я не рассеян -- я сосредоточен на своей задаче. ;)
            Совершенно не согласен с тем, что нужно использовать регистры.
            Регистры СОВСЕМ нельзя использовать (в запросах 1С я имею ввиду, не в SQL) если в запросе присутствует конструкция Регистр.ХХХ.ТекущийДокумент.УУУУ
            Встретился мне раз такой маразм. Был какой-то отчет по экспедиторам, выполнялся по ОДНОМУ около 20мин; хотел переписать под SQL, но проблема решилась на замену выборки из регистра на выборку по документам отгрузки. Стал делаться за 30сек :-)

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

            На регистре, который часто приходится рассчитывать, полезно ставить галочку быстрый отбор, отбор движений по имзмерениям и т.д. Наприме, регистры учета остатков, которые рассчитываются в момент проведения документов. Установка всех этих галочек замедляет запись в регистр, но ускоряет чтение из него. А чтение занимает 80-95% времени.

            Нужно избегать проведения документов задним или будущим числом - мало того, что это замедляет работу, так еще и в данных после этого бывает разобраться очень и очень трудно. Но, к сожалению, тут от программиста мало что зависит...

            бухгалтерский учет (до какого-то предела, наверное) гораздо быстрее работает на ДБФ, чем на SQL. Разница в скорости - в десятки раз. Дело в том, что объект "БухгалтерскиеИтоги" возможности SQL не использует совсем. Написание прямых запросов для SQL в этом случае затруднено, в индекс попасть очень трудно.

            Да! Об этом уже много раз сказано, но я повторюсь:
            для регистра 1С создает кластерный индекс по всем его измерениям, поэтому наивысшая скорость получается при указании в запросе значений для всех измерений (операция INDEX SEEK), приемлемая - при указании нескольких первых измерений (INDEX SCAN), а при указании не первых измерений поиск сводится к просмотру таблицы (TABLE SCAN) - то есть тормоза. Измерения в индексе расположены в том порядке, в котором они объявлены в 1С.
            http://necro.nightmail.ru
              Mechanic, почему то speed_1C.zip не скачивается - ошибка в архиве.
                Всё отлично скачивается :yes:
                [А что Если… КонецЕсли]
                  Плохой стиль :no: :
                  ExpandedWrap disabled
                    Для Н = 1 По Метаданные.Справочник() Цикл
                        С = СоздатьОбъект("Справочник."+Метаданные.Справочник(Н).Идентификатор);
                        С.ВыбратьЭлементы(0);
                        Пока С.ПолучитьЭлемент() = 1 Цикл
                            С.Удалить(1);
                        КонецЦикла;
                    КонецЦикла;


                  Хороший стиль :yes: :
                  ExpandedWrap disabled
                    Для Н = 1 По Метаданные.Справочник() Цикл
                        С = СоздатьОбъект("Справочник."+Метаданные.Справочник(Н).Идентификатор);
                        С.ВыбратьЭлементы(0);
                        Пока С.ПолучитьЭлемент() = 1 Цикл
                            С.Удалить(0);
                        КонецЦикла;
                    КонецЦикла;


                  П.С.:
                  На рабочей базе пробовать настоятельно не советую.
                    RusUdin, а ты в курсе, что выборка сбивается при удалении элемента?
                      Цитата evGenius @
                      RusUdin, а ты в курсе, что выборка сбивается при удалении элемента?

                      Проверял. Самое интересное, что не сбивается (релиз 25 по крайней мере).
                        Цитата RusUdin @
                        Проверял. Самое интересное, что не сбивается (релиз 25 по крайней мере).

                        А если удалять не все, а по какому-нибудь условию?
                          Цитата evGenius @
                          А если удалять не все, а по какому-нибудь условию?

                          Не могу сказать, таких задач перед собой не ставил. Но знаю, что с таблицами значений такое не проходит.
                          Сообщение отредактировано: RusUdin -
                            Цитата Allaire @
                            В итоге время построения отчета с условиями больше чем без оных!

                            Это неверно... С условиями запрос отрабатываютса на много быстрее, тем более если это запрос на ToySQL или на 1С++

                            -Added
                            Цитата , @
                            Плохой стиль :
                            Для Н = 1 По Метаданные.Справочник() Цикл
                            С = СоздатьОбъект("Справочник."+Метаданные.Справочник(Н).Идентификатор);
                            С.ВыбратьЭлементы(0);
                            Пока С.ПолучитьЭлемент() = 1 Цикл
                            С.Удалить(1);
                            КонецЦикла;
                            КонецЦикла;


                            Хороший стиль :
                            Для Н = 1 По Метаданные.Справочник() Цикл
                            С = СоздатьОбъект("Справочник."+Метаданные.Справочник(Н).Идентификатор);
                            С.ВыбратьЭлементы(0);
                            Пока С.ПолучитьЭлемент() = 1 Цикл
                            С.Удалить(0);
                            КонецЦикла;
                            КонецЦикла;


                            П.С.:
                            На рабочей базе пробовать настоятельно не советую.

                            В двох случаях стиль плохой, хотя и в обох верный.

                            Хороший Стиль:

                            ExpandedWrap disabled
                               
                              Для Н = 1 По Метаданные.Справочник() Цикл
                                  Спр = СоздатьОбъект("Справочник."+Метаданные.Справочник(Н).Идентификатор);
                                  Спр.ВыбратьЭлементы(0);
                                  Пока Спр.ПолучитьЭлемент() = 1 Цикл
                                      //где РежимУдаления - это зависит от того где вы реализируете код, если обработка можно поместить флаг
                                      //можно спросить в пользователя
                                      ~Удалить:Попытка
                                        Спр.Удалить(РежимУдаления);
                                      Исключение
                                        //можно обрабатаывать разными методами, я испльзую переход
                                        Ответ = Вопрос("Элемент: "+Спр.Код+" "+Спр+" заблокирован, повторить","Да+Нет+Отмена");
                                        Если Ответ = "Да" Тогда
                                           Перейти ~Удалить;
                                        ИначеЕсли Ответ = "Нет" Тогда
                                           Сообщить("Элемент был заблокирован и не удален/помечен"+Спр.Код+ "" +Спр,"!!!");
                                           Продолжить;
                                        Иначе
                                           //тут можна сделать обрів и общего цикла
                                           Прервать;  
                                        КонецЕсли;
                                      КонецПопытки;
                                  КонецЦикла;    
                              КонецЦикла;
                            Сообщение отредактировано: logarifm -
                              Цитата logarifm @

                              ExpandedWrap disabled
                                Для Н = 1 По Метаданные.Справочник() Цикл
                                    Спр = СоздатьОбъект("Справочник."+Метаданные.Справочник(Н).Идентификатор);
                                    Спр.ВыбратьЭлементы(0);
                                    Пока Спр.ПолучитьЭлемент() = 1 Цикл
                                        //где РежимУдаления - это зависит от того где вы реализируете код, если обработка можно поместить флаг
                                        //можно спросить в пользователя
                                        ~Удалить:Попытка
                                          Спр.Удалить(РежимУдаления);
                                        Исключение
                                          //можно обрабатаывать разными методами, я испльзую переход
                                          Ответ = Вопрос("Элемент: "+Спр.Код+" "+Спр+" заблокирован, повторить","Да+Нет+Отмена");
                                          Если Ответ = "Да" Тогда
                                             Перейти ~Удалить;
                                          ИначеЕсли Ответ = "Нет" Тогда
                                             Сообщить("Элемент был заблокирован и не удален/помечен"+Спр.Код+ "" +Спр,"!!!");
                                             Продолжить;
                                          Иначе
                                             //тут можна сделать обрів и общего цикла
                                             Прервать;  
                                          КонецЕсли;
                                        КонецПопытки;
                                    КонецЦикла;    
                                КонецЦикла;


                              Имхо тоже плохой стиль.
                              1) Использовать конструкцию Перейти нужно только в крайнем случае.
                              2) В подобных случаях необходимо использовать механизм тразакций.
                              Мне не нужен код. Мне нужны безумные идеи. Незамыленный взгляд стороннего наблюдателя. Ссылки по обсуждаемой проблеме.
                                Цитата Pavlovsky @
                                2) В подобных случаях необходимо использовать механизм тразакций.

                                Причём если справочники в базе объёмные, то транзакцию нужно делать не одну, а порциями по некоторому количеству данных. Иначе удаление будет дико тормозить и отожрёт очень много памяти.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1460 ]   [ 17 queries used ]   [ Generated: 18.07.19, 13:23 GMT ]