Акт по журналу 1С: справка с 817 до 145 мс, проверка заказа с 301 до 2 мс, 9353 руб. в год
Разработка - Инструментарий разработчика
Файлы
ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.
Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний
Оформите подписку на компанию для решения рабочих задач
Оформить подписку и скачать решение со скидкойВы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
logcfg.xml с отбором по модулю сценария; те же вызовы засечены секундомером без журнала и с журналом.Проценты от выгоды платят по числам, с которыми согласны обе стороны, поэтому метод замера, формула и источник каждого числа записываются до начала работ. Технологический журнал даёт для этого базу: ключ операции, число обращений к данным и время каждого вызова, а скрипт превращает его в таблицу акта.
- Операция в журнале определяется внешней строкой контекста, то есть местом кода, откуда пошёл вызов; её ключ вносится в приложение к договору.
- Семь повторов в новых процессах показывают разброс: справка «до» шла от 561,9 до 1172,0 мс, «после» от 109,0 до 297,0 мс.
- Контрольная операция, код которой не менялся (цена позиции), остаётся в таблице: 8,7 и 0,0 мс по журналу (это шаг часов, см. ниже), 10,3 и 9,1 мс по секундомеру.
- Журнал замедляет вариант «до» в 1,75 раза (на 369,8 мс) и вариант «после» в 1,81 раза (на 86,0 мс), поэтому выгода по журналу (9353 руб.) почти вдвое выше выгоды секундомера без журнала (4939 руб.).
- Частота и ставка берутся из договора; осторожная оценка (самый быстрый «до» и самый медленный «после») записывается в акт рядом со средней.
в акте стоит число, которое каждая сторона может повторить своей командой на тех же журналах, а разница между журналом и секундомером указана в самом акте.
Для кого: консультанты и разработчики 1С, которые берут оплату за ускорение базы от выгоды заказчика и хотят подкрепить договор базой замеров, повторяемой скриптом.
Договор «оплата от выгоды» держится на одном документе: акте, где записано, сколько времени операция занимала до работ, сколько после, и как из этой разницы получены часы и рубли. Я собрала такой акт на файловой базе «Нано-УТ 2.0»: включила технологический журнал, семь раз выполнила один и тот же сценарий до оптимизации кода и семь раз после, а таблицу для акта получила скриптом tj_baseline.py. Частоту операций и ставку часа я задала сама, как это делает приложение к договору.
Стенд и порядок работы
| Условие | Значение |
|---|---|
| Платформа | 1С:Предприятие 8.3.27.2130 x86, файловая база, COM-соединение из 32-битного PowerShell |
| Конфигурация | «Нано-УТ 2.0»; в оба варианта добавлен общий модуль ЗамерСценарий (подготовка данных и три операции) |
| Данные | 300 товаров, одно проведённое поступление на сумму 1 035 000,00, склад, два контрагента, вид цены; данные синтетические |
| Инструмент | tj_baseline.py, Python 3.12.10, только стандартная библиотека |
| Компьютер | Windows 11 Pro, Intel Core i5-2400, 7,9 ГБ ОЗУ, SATA SSD |
| Повторы | 7 для варианта before и 7 для after, каждый повтор в новом процессе, варианты чередовались |
| Журнал | события SDBL и DBV8DBEng с отбором по подстроке ЗамерСценарий в контексте |
Выводы относятся к файловой базе и к одному виду исправления. На клиент-серверном варианте с несколькими пользователями скрипт не запускался, и акт для такой базы потребует отдельного замера.
Три операции для замера
Сценарий состоит из трёх вызовов общего модуля, каждый возвращает строку, чтобы сравнить результат до и после:
| Операция | Что делает | Менялась ли |
|---|---|---|
ФормыСервер.Справка(Документ) |
справка по остаткам и резервам для каждой строки документа продажи | да |
СкладСервер.ПроверитьДоступность(Заказ) |
проверка доступности заказа клиента по всем строкам | да |
ЦеныСервер.ЦенаНаДату(Товар, ВидЦены, Дата) |
цена одной позиции на дату | нет, контрольная |
В обеих изменённых процедурах до правки запрос выполнялся на каждую строку внутри цикла. Для проверки доступности это выглядело так:
После правки один запрос по списку номенклатуры возвращает остатки всех строк, а цикл читает их из соответствия:
Справка переписана так же: два запроса на строку (остатки и резервы) заменены двумя запросами на весь список. Полный текст обоих вариантов собирает stand/make_stand.py из архива инструмента.
Прежде чем сравнивать время, я сравнила результаты. Хеши результатов справки на 1, 7, 150 и 300 строках и ответы проверки доступности на 1, 150 и 300 строках (с нехваткой остатка и без) в обоих вариантах совпали (evidence/equality.txt). Оба варианта прошли /CheckModules без ошибок.
Как собирается журнал
Журнал включается файлом logcfg.xml. В нём два отбора, по событиям SDBL (обращения к данным) и DBV8DBEng (файловый движок), и фильтр по подстроке контекста, чтобы чужие сеансы в журнал не попали:
В каталог conf установки платформы на этом компьютере записать нельзя, и платформа прочитала файл из C:\ProgramData\1C\1cv8\conf. Опыт создаёт этот каталог на время повторов и удаляет после них. После опыта я проверила каталоги, куда платформа могла бы читать общий файл: в C:\Program Files (x86)\1cv8\conf, в bin\conf версии 8.3.27.2130 и в ProgramData файла logcfg.xml нет (evidence/logcfg-location.txt).
Порядок одного повтора: записать logcfg.xml, запустить новый процесс 1С через COM, выполнить три операции, закрыть процесс, сложить каталог журнала в before-rN или after-rN. Хеши SHA-256 всех четырнадцати файлов журнала записаны в evidence/tj-sha256.txt: для договора это способ зафиксировать период «до», чтобы стороны подписали его до начала работ.
Что показал журнал
Скрипт склеивает события в вызовы. Вызов это непрерывная серия событий с одним ключом: от начала первого до конца последнего. Ключом служит внешняя строка контекста, то есть строка модуля сценария, откуда вызвана операция; ключ хранится целиком, без обрезки, а сокращается только текст в консоли.
Граница между двумя вызовами в журнале не записана, и надёжно найти её по произвольному журналу нельзя: простой порог паузы этого не доказывает. Поэтому инструмент принимает журнал, где каждая операция выполнена в повторе один раз, как в этом опыте: один повтор это один новый процесс, в нём по одному вызову каждой операции. Если одна операция встретилась двумя отдельными сериями (повторный вызов, перемежение с другой операцией, два файла) или внутри серии пауза длиннее 5 секунд, скрипт отвергает повтор с кодом 2 и объяснением. Паузу короче порога и два вызова одного контекста подряд без пауз он не отличит от одного вызова: такие вызовы нужно развести сбором, по одному процессу на повтор.

Рисунок 1. Команда compare на журналах опыта: 7 повторов до и 7 после, в скобках разброс между повторами.
| Операция | Обращений до и после | До, мс | После, мс | p95 до, мс | p95 после, мс |
|---|---|---|---|---|---|
| Справка, 150 строк | 755 и 159 | 817,0 (561,9-1172,0) | 145,0 (109,0-297,0) | 1172,0 | 297,0 |
| Проверка доступности, 150 строк | 300 и 2 | 301,3 (203,0-781,0) | 2,2 (0,0-15,0) | 781,0 | 15,0 |
| Цена позиции (код не менялся) | 1 и 1 | 8,7 (0,0-15,9) | 0,0 (0,0-0,0) | 15,9 | 0,0 |
Обращением к данным здесь считается событие SDBL. У проверки доступности до правки их 300 на 150 строк, по два на строку, а после правки два на весь список; это и объясняет разницу во времени. На семи повторах p95 совпадает с максимумом, поэтому его стоит читать как «худший повтор». Разброс в этом прогоне велик: справка «до» от 561,9 до 1172,0 мс, проверка доступности «до» от 203,0 до 781,0 мс; в четвёртом повторе секундомер с журналом показал для проверки доступности 819,7 мс при 204-262 мс в остальных. Из-за такого разброса в акт кладут и среднее, и осторожную оценку.
Время контрольной операции (8,7 и 0,0 мс) лежит в пределах шума журнала: метки времени событий идут шагами 15-16 мс. Это видно в самом журнале: 1526 событий SDBL дали 88 различных значений времени; из 87 промежутков между соседними значениями 82 равны 15 или 16 мс, остальные пять (31-78 мс) приходятся на паузы между событиями (evidence/tj-clock-step.txt). Поэтому 0,0 мс у быстрого вызова означает «короче шага часов», и результат 2,2 мс у проверки доступности после правки проверен вместе с секундомером.
Сверка с секундомером
Те же вызовы я засекла секундомером вокруг COM-вызова, один раз с включённым журналом и один раз без него. Скрипт сводки stand/wall_summary.py лежит в архиве инструмента.

Рисунок 2. Секундомер вокруг вызова: 7 повторов, 150 строк; сверху журнал выключен, ниже включён.
| Операция | Журнал выключен, до и после, мс | Журнал включён, до и после, мс | Ускорение без журнала |
|---|---|---|---|
| Справка | 492,5 и 106,7 | 862,3 и 192,7 | 4,6 раза |
| Проверка доступности | 162,0 и 16,4 | 315,4 и 17,0 | 9,9 раза |
| Цена позиции | 10,3 и 9,1 | 13,4 и 11,9 | 1,1 |
Таблица даёт следующее.
Журнал замедляет оба варианта, в абсолютных миллисекундах сильнее вариант «до». Справка с журналом идёт 862,3 мс против 492,5 без него, то есть в 1,75 раза дольше (плюс 369,8 мс); после правки 192,7 против 106,7, в 1,81 раза (плюс 86,0 мс). Абсолютный рост соответствует числу записанных событий: у варианта «до» их 755, у варианта «после» 159. Накануне то же сравнение дало 1,34 и 1,15 раза: на кратность накладных расходов журнала рассчитывать нельзя, её нужно мерить на своей базе.
Время по журналу (817,0 мс) близко к секундомеру с журналом (862,3 мс); секундомер без журнала показывает 492,5 мс. Пользователь с выключенным журналом экономит на справке 385,8 мс, журнал даёт 672,0 мс.
Секундомер включает запуск вызова через COM: после правки проверка доступности по журналу занимает 2,2 мс, а секундомер показывает 16,4 мс. Для коротких вызовов секундомер даёт нижнюю границу того, что видит вызывающий код.
От миллисекунд к рублям
Формула в tj_baseline.py benefit записана в самом инструменте и в приложении к договору:
Ухудшение одной операции вычитается из выгоды другой, а отрицательный чистый эффект вознаграждения не даёт. Пример для проверки: одна операция экономит 1 с, другая теряет 2 с, по одному вызову в день, один день, ставка 3600 руб. за час: чистый эффект минус 1 руб., вознаграждение 0. Этот случай закреплён тестами обоих архивов. В примере статьи обе операции стали быстрее, поэтому на его числа правило не влияет.
Параметры примера я задала сама: 120 справок и 300 проверок доступности в рабочий день на всех сотрудников, 247 рабочих дней, 800 руб. за час сотрудника с налогами, доля исполнителя 20 %. В договоре их подтверждает заказчик, журнал их не содержит.
В PowerShell команду записывают одной строкой, без символов ^; в окне консоли на рисунке 3 она выполнена так, без ключей --act и --csv.

Рисунок 3. Команда benefit: часы и рубли по каждой операции, итог и вознаграждение 20 %; в скобках осторожная оценка.
| Источник времени | Часов в год | Рублей в год | Вознаграждение 20 % |
|---|---|---|---|
| Журнал, среднее по 7 повторам | 11,69 | 9353 | 1871 |
| Журнал, осторожная оценка | 6,05 | 4841 | 968 |
| Секундомер без журнала, среднее | 6,17 | 4939 | 988 |
| Секундомер без журнала, осторожная оценка | 5,61 | 4490 | 898 |
Осторожная оценка берёт самый быстрый повтор «до» и самый медленный повтор «после». Команда с ключами и описание источника времени записываются в сам акт. Строки секундомера получены калькулятором calc_csv.py из компаньона на тех же формулах (evidence/calc-stopwatch.txt). Калькулятор принимает средние, округлённые до десятых миллисекунды, поэтому на журнальных числах он даёт 9351 руб. вместо 9353: разница в два рубля идёт от округления входа (evidence/calc-filled.txt).
Расхождение между 9353 и 4939 руб. вызвано разными часами: журнал и секундомер без журнала измеряют разные вещи, и договор должен назвать одни из них. Для приложения я бы записала журнал как способ фиксации периодов «до» и «после», а основанием выплаты назвала осторожную оценку по журналу. В этом опыте 4841 руб. лежат рядом с 4939 руб. секундомера без журнала и ниже них; это наблюдение одного опыта; что осторожная оценка по журналу окажется ниже секундомера на других данных, оно не гарантирует.
Суммы в примере малы: операций две, данных 300 товаров, стенд учебный. Они показывают порядок расчёта. На базе заказчика числа выйдут из его частот и его журналов.
Что записать в приложении к договору
В компаньоне лежит заполненный образец приложения. Его пункты и то, чем каждый подтверждён в опыте:
| Пункт приложения | Что записано | Чем подтверждается |
|---|---|---|
| Операции | ключ из журнала, частота в день, кто выполняет | таблица compare, подпись заказчика под частотой |
| База «до» | метод, число повторов, данные, платформа и железо | каталоги before-r1..r7, tj-sha256.txt |
| Формула | как выше, с параметрами и правилом для ухудшений | benefit, calc_csv.py, тест смешанного результата |
| Целевые показатели | не более 200 мс для справки и не более 50 мс для проверки (среднее по 7 повторам) | таблица после правки |
| Условие совпадения | результат операции совпадает до символа | equality.txt |
| Приёмка | кто запускает повторы после, на какой копии, срок подписания | полная команда benefit с ключами и источник времени записаны в акте |
| Внешние изменения | смена сервера или обновление платформы не пересматривают вознаграждение | отдельный пункт |
Образец содержит и договорные пункты (гарантийный период, срок подписания, внешние изменения) как заготовку. Окончательный текст договора проверяет юрист каждой стороны.
Границы замера
- Журнал должен содержать по одному вызову каждой операции на повтор. Определить по журналу, сколько раз и когда вызывалась операция, скрипт не может; повторные вызовы и перемежение отвергаются, а паузу меньше 5 секунд и два вызова подряд без паузы он считает одним вызовом.
- Скрипт не включает журнал и не запускает 1С: он читает готовые файлы
*.log. Сбор повторов для вашей команды делаетcollect_runs.pyиз компаньона: если в каком-то повторе нет журнала с событиями или команда завершилась ошибкой, сбор останавливается с ненулевым кодом, существующий замер не удаляется без ключа--replace. - Файловая база пишет события SDBL и DBV8DBEng; события CALL и DBMSSQL там не появляются. Разбор клиент-серверных журналов скрипт умеет, но на них он не запускался.
- Часы журнала на этой машине идут шагами 15-16 мс, поэтому вызовы короче 50 мс сверяются секундомером.
- Время до первого и после последнего обращения к данным в журнале не видно: разница с секундомером при включённом журнале составила 45,3 мс у справки «до» и 47,7 мс у справки «после». Полный путь пользователя через клиента замеряется отдельно.
- Скрипт считает время; рубли получаются из частоты и ставки, которые приходят из договора.
- Со временем база растёт, и сегодняшний «после» перестаёт быть сегодняшним. Для этого в приложении есть гарантийный период и пункт о повторных замерах на тех же данных.
Файлы к статье
К статье приложены два архива.
Инструмент perf-fee-24-4-tool.zip содержит tj_baseline.py, 26 тестов, журналы опыта (sample/before-r1..r7 и sample/after-r1..r7) и стенд: make_stand.py собирает варианты before и after из выгрузки «Нано-УТ 2.0», run_experiment.py повторяет опыт, wall_summary.py сводит секундомер. Запуск из корня распакованного архива:
Компаньон perf-fee-24-4-companion.zip содержит заполненный образец приложения к договору, акт замеров этого опыта, калькулятор calc_csv.py с пустым и заполненным CSV, collect_runs.py (сбор повторов для вашей команды), шаблон logcfg.xml, чек-лист аудита из пяти разделов и журналы опыта. Тесты обоих архивов работают без платформы; из чистой распаковки проходят 26 тестов инструмента и 24 теста компаньона (журнал прогона лежит в evidence/unittest-tool.txt и evidence/unittest-companion.txt). В обоих архивах есть SHA256SUMS.txt с хешами всех файлов.

Рисунок 4. Тесты обоих архивов из чистой распаковки: 26 у инструмента и 24 у компаньона, все проходят.
Итог
Технологический журнал и скрипт на 14 повторах дали таблицу для акта: справка быстрее в 5,6 раза по журналу (817,0 против 145,0 мс) и в 4,6 раза по секундомеру без журнала, у проверки доступности 301,3 против 2,2 мс по журналу и 162,0 против 16,4 мс по секундомеру. При условных 120 и 300 вызовах в день и ставке 800 руб. за час это 11,69 часа и 9353 руб. в год по журналу, 4939 руб. по секундомеру без журнала, 4841 руб. по осторожной оценке. Тот же опыт накануне дал 660,7 и 95,9 мс по справке и 6991 руб. по журналу (evidence/previous-run-20261025.txt): числа от прогона к прогону отличаются, поэтому в договор вносят журналы конкретных прогонов; числа из статьи годятся только как образец.
Практический смысл: приложение к договору фиксирует метод, ключи операций и формулу, а акт воспроизводится командой на сохранённых журналах. Различие между журналом и секундомером нужно назвать в приложении к договору (чем фиксируются периоды «до» и «после»), иначе выгода окажется завышена у варианта «до».
Опыт проведён на файловой базе одной машины и на одном виде исправления. Блокировки, нагрузка нескольких пользователей и клиент-серверный режим в него не вошли; частоты и ставка в примере условные.
Вступайте в нашу телеграмм-группу Инфостарт