Себестоимость у нас считается достаточно долго от 30 минут и больше в зависимости от разных факторов.
Используем партионный учет. Списание партий «по средней» в БУ/НУ, по ФИФО в УУ
Как-то раз решил сделать замер производительности чтобы определить какие операции занимают много времени. Замер приложен в файле ЗамерПроведенияСебестоимости.pff.
Меня очень удивило, что почти 10% общего времени выполнялся код:
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Вроде бы ничего криминального, но этот код выполнялся в моем случае в двух местах в общей сложности более 159 млн раз!
Стал смотреть где и как используется структура «СтруктураСостояния» и обнаружил, что как структура-то собственно она нигде не используется. Везде используется только ее ключ. Поэтому было решено отказаться от этой структуры и перейти к массиву. Так как в коде требовалось использовать как все ключи этой струтуры, так и все кроме «ВременнаяРазница» и «ПостояннаяРазница», то решено было создать два массива.
В приложенном файле КорректировкаСтоимости_РассчитатьСписаниеПоСредней.txt находится уже готовая к применению процедура — просто замените штатную.
Для тех кто не имеет доступ к скачиванию распишу, что исправил в процедуре РассчитатьСписаниеПоСредней() из общего модуля КорректировкаСтоимости УПП 1.3.37.1 (вообще эта процедура не менялась со времен как минимум 1.2.16.1)
Для возможности сравнения времени операции в начало процедуры добавим (учитываем, что ТекущаяУниверсальнаяДатаВМиллисекундах() появилась только в 8.2.17, для более ранних используем просто ТекущаяДата())
// ША
НачалоОперации = ТекущаяУниверсальнаяДатаВМиллисекундах();
ИспользоватьМассивы = Истина;
// ША
После кода
СтруктураСостояния = Новый Структура;
Добавим
// ША
Если ИспользоватьМассивы Тогда
МассивСостояний = Новый Массив;
МассивСостоянийБР = Новый Массив;
КонецЕсли;
// ША
После кода
СтруктураСостояния.Вставить(Колонка.Имя)
Добавим
// ША
Если ИспользоватьМассивы Тогда
МассивСостояний.Добавить(Колонка.Имя);
Если Не Колонка.Имя = «ВременнаяРазница» И Не Колонка.Имя = «ПостояннаяРазница» Тогда
МассивСостоянийБР.Добавить(Колонка.Имя);
КонецЕсли;
КонецЕсли;
// ША
Код
НайденоСостояние=Истина;
Для Каждого Элемент Из СтруктураСостояния Цикл
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Продолжить;
КонецЕсли;
Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ]) Тогда
НайденоСостояние = Ложь; // состояния различны
Прервать; // дальше можно не проверять
КонецЕсли;
КонецЦикла;
Заменим на
НайденоСостояние=Истина;
// ША
Если ИспользоватьМассивы Тогда
Для Каждого Элемент Из МассивСостоянийБР Цикл Если ЭлементСостояние.Значение[Элемент] <> Строка[Элемент] Тогда НайденоСостояние = Ложь; Прервать; КонецЕсли; КонецЦикла;
Иначе
// ША
Для Каждого Элемент Из СтруктураСостояния Цикл
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Продолжить;
КонецЕсли;
Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ]) Тогда
НайденоСостояние = Ложь; // состояния различны
Прервать; // дальше можно не проверять
КонецЕсли;
КонецЦикла;
КонецЕсли; // ША
Код
// Переносим в соответствие
СтрСост = Новый Структура;
Для Каждого Элемент Из СтруктураСостояния Цикл
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Продолжить;
КонецЕсли;
СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]);
КонецЦикла;
Заменим на
// Переносим в соответствие
СтрСост = Новый Структура;
// ША
Если ИспользоватьМассивы Тогда
Для Каждого Элемент Из МассивСостоянийБР Цикл СтрСост.Вставить(Элемент, Строка[Элемент]); КонецЦикла;
Иначе
// ША
Для Каждого Элемент Из СтруктураСостояния Цикл
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Продолжить;
КонецЕсли;
СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]);
КонецЦикла;
КонецЕсли; // ША
Код
НайденоСостояние=Истина;
Для Каждого Элемент Из СтруктураСостояния Цикл
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Продолжить;
КонецЕсли;
Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]) Тогда
НайденоСостояние = Ложь; // состояния различны
Прервать; // дальше можно не проверять
КонецЕсли;
КонецЦикла;
Заменим на
НайденоСостояние=Истина;
// ША
Если ИспользоватьМассивы Тогда
Для Каждого Элемент Из МассивСостоянийБР Цикл Если ЭлементСостояние.Значение[Элемент] <> Строка[Элемент + ПрефиксПараметровНовогоСостояния] Тогда НайденоСостояние = Ложь; Прервать; КонецЕсли; КонецЦикла;
Иначе
Для Каждого Элемент Из СтруктураСостояния Цикл
Если Элемент.Ключ = «ВременнаяРазница» или Элемент.Ключ = «ПостояннаяРазница» тогда
Продолжить;
КонецЕсли;
Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]) Тогда
НайденоСостояние = Ложь; // состояния различны
Прервать; // дальше можно не проверять
КонецЕсли;
КонецЦикла;
КонецЕсли; // ША
Код
// Переносим в соответствие
СтрСост = Новый Структура;
Для Каждого Элемент Из СтруктураСостояния Цикл
СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]);
КонецЦикла;
Заменим на
// Переносим в соответствие
СтрСост = Новый Структура;
// ША
Если ИспользоватьМассивы Тогда
Для Каждого Элемент Из МассивСостояний Цикл СтрСост.Вставить(Элемент, Строка[Элемент+ПрефиксПараметровНовогоСостояния]); КонецЦикла;
Иначе
Для Каждого Элемент Из СтруктураСостояния Цикл
СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]);
КонецЦикла;
КонецЕсли; // ША
Для анализа эффекта от кода будем записывать время выполнения процедуры в журнал регистрации. Для этого в конце процедуры добавим
// ША
ЗаписьЖурналаРегистрации(«СписаниеПоСредней, сек», УровеньЖурналаРегистрации.Предупреждение, , ,
Формат((ТекущаяУниверсальнаяДатаВМиллисекундах() — НачалоОперации) / 1000, «ЧДЦ=3; ЧГ=0»));
// ША
Теперь меняя всего одну строку (ИспользоватьМассивы = Истина/Ложь) в модуле мы можем проверить эффект от предложенных манипуляций. В моем случае время выполнение этой процедуры сократилось примерно в два раза, что уменьшило время расчета себестоимости на величину порядка 7-10 минут. Конечно это не ускорение расчета себестоимости в разы, но неплохое начало оптимизации
Так же значительно ускорилось время проведения документа «Корректировка стоимости списания товаров»
Тестируем, отписываемся о результатах полученных на ваших базах
Отредактировано 13.03.2013
1) Указал что используем партионный учет
2) Добавил пропущенное в тексте статьи заполнение массивов (в прикрепленном файле это было)
3) Добавил, что ускорилось время проведения документа «Корректировка стоимости списания товаров»
Для раскраски кода применялась Разукрашка
Пример хоть и корявой, но реальной оптимизации УПП 🙂
И не просто «сферической» УПП, а самого коварного блока — расчет себестоимости.
(0) Антон Ширяев,
а от чего конкретно зависит столь великое число итераций? Объем регистра, активное использование определенных документов?
Вот только, автор не указал режим учета затрат: РАУЗ или традиционный учет.
(3) Kom-off,
ну этот блок точно не РАУЗ 🙂
(4) Да, чудес на свете много.
Поди, знай! (с) Интерны
(3) Kom-off,
РАУЗ чем и «хорош» (хотя я наоборот — склонен сказать в данном случае «плох»), что не считает «тупо» все, что попало в период, а на основе показателей (которых набирается на порядки меньше, чем реальных исходных данных, «давших» (сформировавших) эти показатели), дает «приближенную» картину по себестоимости каждого товара.
1С считает, что картина «и так сойдет».
Я же считаю — что даже и для сельской местности нужно быть ответственнее и профессиональнее.
Точно «в тютельку» РАУЗ, по-моему, считает только по НДС (отдельным регистром и расчетом) — тут им (1С-у) просто налоговая не дает безобразничать 🙂
(2)
На самом деле пока не вникал какие именно операции дают столь большие исходные таблицы «ТаблицаТоваров», но очевидно что есть три вложенных цикла которые и дадут столь большой объем итераций.
Плюс ко всему процедура при расчете себестоимости вызывается многократно. Сколько длился каждый вызов покажет журнал регистрации.
(3) Kom-off,
Используется партионный учет
(7) Антон Ширяев,
т.е. зависит здесь просто зависит напрямую от количества товаров в периоде, за который рассчитывается себестоимость?
(6) Какой-то поток сознания.
(10) Kom-off,
предлагаю озвучить «свое» понимание РАУЗ.
Не возбраняется 🙂
А остальные послушают.
Только без копи-паста 1совых агиток, а как сам вот понял — так и руби.
(10) Kom-off,
или напишите сразу — «ниасилил» 🙂
Ни РАУЗ, ни «потоки сознания».
Только — адаптированные для 1сников агитки 1С.
(12) Без агиток — расчет системы линейных уравнений. Чего тут понимать то?
(12)
Нет. Я так не скажу. «Звиняй», барин.
(13) Kom-off,
конечно 🙂
браво. Достойный ответ 1сника, читавшего агитки 🙂
А что рассчитывают эти ЛУ? Какие исходные данные подставляются в уравнения?
(15) мальчик, читай умные книжки, и РАУЗ посетит тебя.
(16) Кадош,
так, еще один юноша пожаловал 🙂
Вас посетил РАУЗ уже? Прошу, в двух словах — что это такое.
А иначе — в контейнер с остальными, «знающими» РАУЗ от 1С.
(17) Вот любитель хамить.
Что тут скажешь: тролль — он и в Африке тролль.
Одно чего стоит:
В двух словах уже сказано было, названо было агиткой и опять по кругу. Молодец!
(16) Кадош,
… хоть бы поискал сначала по инету инфо, что книжек по 1С-РАУЗу — нет.. брошюрки и невнятная методичка с Украины Абрашиной..но куда ж там…
короче, контейнер…
(18) мдя…ты книжки читать пробовал?
жене сказал — что поехал в командировку,
любовнице сказал — что поехал в колхоз на картошку,
а сам на чердак и …..
Оптимизировать, оптимизировать и еще раз оптимизировать!!!
Для возможности сравнения времени операции в начало процедуры добавим (учитываем, что ТекущаяУниверсальнаяДатаВМиллисекундах() появилась только в 8.2.17, для более ранних используем просто ТекущаяДата())
(21)
для тех, кто не осчастливлен платформой 8.2.17:
Показать
—
StepByStep
http://infostart.ru/public/165702/
этот пример любезно предложил
в своей статье
(18) для теоретиков. В одной из ЖКК есть подробный разбор РАУЗа с расчетами и формулами.
Фас, ищи.
Если в этом месте потребуется еще ускорить, даже ценой большего использования памяти, то попробуйте заменить эти многократные проверки равенства строк текстовым константам на проверки равенства чисел или логических переменных. Например, если один раз пройти по структуре или по массиву, и заполнить добавочные элементы примерно так:
Если Элемент.Ключ = «ВременнаяРазница» тогда
Элемент.ПризнакВР = Истина;
КонецЕсли;
то потом вместо сравнений Если Элемент.Ключ = «ВременнаяРазница» Тогда
можно использовать Если Элемент.ПризнакВР Тогда
Это может дать большой выигрыш на многомиллионных повторах.
(24) kapustinag,
Дело в том, что это уже не нужно 🙂
Для этого и создано два массива, чтоб закешировать в них только нужные элементы и не проверять условие в цикле
(23) Кадош,
а на Марсе яблони цветут.
Сам факт того, что даже не знаешь — «в каком ЖКК», да еще и подробный (!) разбор, говорит сам за себя.
(27) Кадош,
задвинься в угол контейнера, друг.
Когда хоть что-то будешь знать — приходи.
А пикироваться с тобой на уровне «В одной из ЖКК» и «Наверняка больше азбуки» — у меня нет времени. Наверняка у тебя есть сотня таких же московских деятелей, равных по разуму, которые с удовольствием продолжат тренд про школу и «там где-то что-то должно же быть», с которыми ты более приятно проведешь время.
(28) Ты уже показал себя во всей красе постом о том, что расчет себестоимости с помощью РАУЗ происходит с точностью +- километр. Ах тысячи несчастных российскийх предприятий! Прежде чем выдавать такие тезисы, надо было поработать с РАУЗ хотя бы на 1-2 предприятих.
Ах, да. В вашей деревне только ларьки, которым требуются эникейщики вроде тебя, «компьютерные монстры» так сказать.
(29) Кадош,
Если на каких-то несчастных предприятиях деятели вроде тебя «внедрили» (включили галочки) РАУЗ — это не значит, что на предприятии теперь полная прозрачность в учете и реальная цифра на выходе расчета себестоимости.
И живут они, бедные, по принципу «что-то считает — ну и ладно».
(28)
вот и читайте книжки (хотя они несут минимум информации) (с) AlexO
Понял, что книги не несут для тебя полезной информации.
Извиняй, друх.
(30) Кадош,
спасибо за цитирование, но 2 листа агиток 1С я не считаю за «книжки».
Уж извиняйте.
А «водонасыщенные» методички, которые вы так громко назвали «ЖКК» никакой инфо, кроме «как включить учет по РАУЗ», не несут.
(28)
Судя по количеству постов автора (28) — нас зло обманывают 🙂
(30) Кадош,
И не надо меня принимать в ваше московское общество «избранных».
Я не такой 🙂
Просто «извиняй, друг» достаточно.
(33) Kom-off,
ну вас, может, и обманывают — но, верно, «и сам обманываться рад» (с) 🙂
А мне еще ни на один вопрос здесь ни вы, ни другие, кроме автора статьи, не ответили по предмету.
(чтобы не возникло новых «подпрыгиваний» вокруг этой фразы — не привели ни одного понимания; если понятно выражаюсь).
(31) бгггг…палишься. РАУЗ это не галочки.
(32) скажи сразу, что уровень умственного развития не позволяет понимать ЖКК.
(34)
Да и сами Вы, сударь, ничего путного по этому вопросу не сказали, однако.
Как говорится:
(с) Иван Крылов. Зеркало и обезъяна.
Если учесть, что на блоке себестоимости в 1С сидят наиболее крутые перцы, то автору тем-более большой жирный плюс
(38) hasp_x,
простите пожалусто за нескромный вопрос:
а что именно у тех самых перцев СамоеЕ крУТое ???
(0) плюсую за находчивость и сообразительность! 🙂
…однажды основательно поменял код типовой конфы (в БП 2.0 механизмы учета ОС — практически всю подсистему переписал), увеличил производительность алгоритмов.
Но привычки критически относиться к коду типовых конфигураций в тот раз не сформировалось.
А теперь на уровне подсознания зафиксировался вопрос: а не прогнать ли тест на производительность?
Исправил и немного дополнил статью
1) Указал что используем партионный учет
2) Добавил пропущенное в тексте статьи заполнение массивов (в прикрепленном файле это было)
3) Добавил, что ускорилось время проведения документа «Корректировка стоимости списания товаров»
4) Исправил версию УПП на которой проверял — обновил до 1.3.37.1
(41) Антон Ширяев,
Да там годами ничего не меняется 🙂
Не то, что в версиях.
рауз — идея хорошая…. но как всегда 1с реализация ж..а
и навязывание ее еще большая зад..ца
особенно в ут… просто ….
ихние теоретики хромают что с практикой … да и теорией ….
РАУЗ..рауз…
единственная книга ко мне в руки попала в 170 страничек (отечественная), надеюсь ее в сети еще не затерли, а то старался… картинки сляпывал:)
А вот с расчетом себестоимости у меня засада — у всех главбухов жажда — закрыть счет 20 за каждый день. И стандартный механизм расчета себестоимости «доломали» до состояния расчета с/с за каждый день.
Мне жалко усилий парниши-программера… Если расчет с/с вне зависимости -за один день или месяц у меня укладывается в полчаса — это «щастье»! А, в довесок, и если при этом не весят все остальные (операторы на реализации)…а это редкость:(
за РАУЗ как таковой будущее расчета себестоимости, так что нам, программерам «пилить» да «пилить».