Исследование нелинейной деградации платформенной записи ODS на больших объёмах данных

20.07.26

База данных - HighLoad оптимизация

Исследование нелинейной деградации платформенной записи ODS на больших объёмах данных: почему время записи растёт быстрее размера документа, как на это влияет содержимое ячеек и что происходит внутри файла. Разбор причин и линейные альтернативы — собственный писатель с переносом оформления и прямая потоковая запись. К публикации приложена обработка-бенчмарк для воспроизведения замеров на любой базе.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Исследование нелинейной деградации платформенной записи ODS на больших объёмах данных
.epf 28,87Kb
0 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Все измерения выполнены на платформе 8.3.27.1989 приложенной обработкой-бенчмарком; цифры в статье — из одного сводного прогона (10 точек от 5 до 50 тысяч строк) и файлов, записанных в этом прогоне. На других версиях платформы поведение может отличаться — обработка позволяет воспроизвести замеры на своей.

 

Постановка задачи

Задача: выгрузить плоскую таблицу — большое количество однотипных строк с несколькими десятками колонок (строки, числа, даты) — в файлы XLSX и ODS с одинаковыми данными. Табличный документ формируется один раз по макету, затем записывается в файлы штатными средствами платформы:

ТабличныйДокумент.Записать(ИмяФайлаXLSX, ТипФайлаТабличногоДокумента.XLSX);
ТабличныйДокумент.Записать(ИмяФайлаODS, ТипФайлаТабличногоДокумента.ODS);

При нагрузочном тестировании выгрузки выявлена особенность: второй вызов — запись ODS — занимает кратно больше времени, чем запись тех же данных в XLSX, и на него приходится основная часть времени выгрузки.

Готовых объяснений этой особенности найти не удалось — пришлось разбираться самостоятельно. Статья повторяет путь исследования по порядку: замеры зависимости времени записи от размера документа, поиск причины деградации и два решения.

 

Как деградирует запись ODS с ростом документа

Методика

Замеряется только запись: документ фиксированного содержания формируется на нужное число строк, время вызова Записать() фиксируется в коде через ТекущаяУниверсальнаяДатаВМиллисекундах(). Каждая точка — отдельный документ, размеры от меньшего к большему; данные генерируются с фиксированным зерном, поэтому прогоны воспроизводимы.

Штатный «Замер производительности» конфигуратора для таких сравнений неприменим: он инструментирует каждую строку встроенного языка, но не платформенные вызовы, и искажает соотношение вариантов — код из множества строк встроенного языка под инструментированием дорожает кратно, одиночный платформенный вызов почти нет. Все цифры в статье получены фиксацией времени в коде.

 

Результаты

Документ строится стандартным способом — выводом области макета с подстановкой параметров, данные содержат строковые и числовые колонки (профиль типичного отчёта). Время платформенной записи ODS по размерам:

 

Строк Запись ODS, с Цена строки, мс
5 000 16,62 3,32
10 000 49,39 4,94
15 000 76,82 5,12
20 000 108,91 5,45
25 000 182,01 7,28
30 000 271,65 9,06
35 000 397,77 11,36
40 000 555,28 13,88
45 000 808,98 17,98
50 000 1115,77 22,32

 

Число строк выросло в 10 раз, размер получающегося файла — тоже в 10 раз (с 9,9 до 99,1 МБ), а время записи — в 67 раз; удельная цена строки поднялась с 3,32 до 22,32 мс, в 6,7 раза. Рост не просто быстрее линейного — он ускоряется с размером: на первой половине диапазона цена строки прибавляет проценты от точки к точке, на второй — разы. Документ на 50 тысяч строк платформа записывает 18,6 минуты.

Для сравнения тем же способом замерена запись XLSX того же ряда документов: удельная цена строки практически не меняется с размером — запись XLSX линейна.

Этим объясняется, почему эффект не проявляется при обычном тестировании на малом количестве данных: на десятках и сотнях строк ODS записывается за секунды, и разница с XLSX не бросается в глаза. Деградация становится заметной только на больших объёмах — поэтому и поймана она была именно нагрузочным тестированием.

 

От чего на самом деле зависит скорость записи

Причина деградации не была очевидна. Выяснить её удалось методом проб и ошибок: изменяли по одному фактору и сравнивали время записи и внутреннее устройство получающихся файлов.

 

Первая гипотеза — способ формирования документа (ложный путь)

Сначала предположили, что дело в способе формирования: вывод заранее подготовленных неизменяемых строк давал линейную запись и единичные автоматические стили в content.xml файла, а стандартный вывод области макета с подстановкой параметров — рост времени и множество стилей. Гипотеза выглядела правдоподобно, но не пережила контрольного эксперимента: при одинаковом способе вывода и разном содержимом ячеек деградация появлялась и исчезала независимо от способа. Способ формирования влияет на постоянную стоимость строки, но не он причина нелинейности.

 

Контрольный эксперимент: содержимое числовых колонок

Решающий эксперимент устроен так (он же — пара линий 1–2 приложенного бенчмарка). Два документа формируются одинаково: вывод области макета с подстановкой параметров на каждую строку, один макет, одни и те же строковые колонки. Единственное отличие — содержимое восьми числовых колонок: в первом документе они заполнены буквенными строками, во втором — числами.

 

Строк Буквы: запись, с мс/стр Числа: запись, с мс/стр
5 000 7,13 1,43 16,62 3,32
10 000 13,81 1,38 49,39 4,94
15 000 20,87 1,39 76,82 5,12
20 000 27,56 1,38 108,91 5,45
25 000 34,77 1,39 182,01 7,28
30 000 42,90 1,43 271,65 9,06
35 000 48,26 1,38 397,77 11,36
40 000 56,35 1,41 555,28 13,88
45 000 62,94 1,40 808,98 17,98
50 000 70,17 1,40 1115,77 22,32

 

Документ с буквенным содержимым записывается строго линейно: цена строки 1,38–1,43 мс по всему диапазону, разброс в пределах процентов. Документ с числами деградирует. На 50 тысячах строк разница между документами — 70 секунд против 1116, в 16 раз — при полностью одинаковом способе формирования. Деградацию вызывает числоподобное содержимое ячеек.

 

Вид содержимого, вызывающего деградацию

Дополнительные наблюдения уточняют картину:

  • Типизированные числа — основной источник деградации.
  • Числоподобные тексты. Замена чисел заранее отформатированными строками вида «12345,67» не помогает: деградация воспроизводится в полном объёме — платформа распознаёт содержимое, похожее на число, и обрабатывает такую ячейку по «числовому» пути.
  • Количество числоподобных колонок. Зависимость на 10 000 строк (0/1/2/4/8 числовых колонок из 77): 1,4 / 1,7 / 2,4 / 3,1 / 4,9 мс/строку. Эффект накапливается плавно, пропорционально числу числоподобных ячеек; порогового значения нет.
  • Объём данных как таковой роли не играет: удлинение текстов, увеличивающее файл в несколько раз, меняет время записи на десятки процентов, тогда как добавление числовых колонок при сопоставимом размере файла меняет его в разы.

 

Анализ содержимого файла

Формат ODS — zip-контейнер, автоматические стили ячеек лежат в content.xml. Сравним файлы, записанные в сводном прогоне на точке 10 000 строк:

 

Файл (10 000 строк) Ячеечных стилей в content.xml
Платформа, документ с буквами 137
Платформа, документ с числами 80 132

 

Восемь числовых колонок на 10 000 строк — это 80 000 числоподобных ячеек: платформа завела отдельный стиль практически на каждую. У буквенного документа тех же размеров стилей 137 — в 585 раз меньше.

Проверяется самостоятельно: обработка сохраняет файлы каждого замера в указанный каталог — достаточно распаковать файл и посчитать вхождения style:family="table-cell" в content.xml. Данные генерируются с фиксированным зерном, поэтому на тех же размерах получатся те же числа.

 

Модель наблюдаемого поведения

При записи ODS платформа типизирует ячейки по содержимому. Ячейкам с числоподобным содержимым она создаёт индивидуальные записи стилей — практически по стилю на ячейку; их совокупность растёт с размером документа, и обработка каждой следующей строки дорожает. Отсюда нелинейность, ускоряющаяся с размером: чем больше в документе числоподобных ячеек, тем быстрее растёт стоимость. Запись XLSX тех же документов к содержимому нечувствительна и остаётся линейной.

Оговорка: внутреннее устройство платформы закрыто, модель реконструирована по наблюдаемому поведению. Она согласуется со всеми измеримыми фактами: линейностью буквенных документов при любом способе формирования, деградацией на числоподобном содержимом, пропорциональностью числу числоподобных ячеек и количеством стилей в файле.

 

Решение 1: собственная запись ODS из табличного документа

Универсальное решение — процедура, записывающая готовый ТабличныйДокумент в файл ODS без платформенного Записать():

ЗаписатьТабличныйДокументВФайлODS(ТабДок, ИмяФайла, ПереноситьОформление = Истина)

 

Контейнер по спецификации ODF 1.2

ODS-файл — zip-контейнер:

  • mimetype — тип документа; по спецификации размещается первым файлом и без сжатия (платформенная запись размещает его не первым и сжатым — LibreOffice это допускает);
  • META-INF/manifest.xml — перечень файлов контейнера;
  • content.xml — данные и автоматические стили;
  • styles.xml, meta.xml — стили документа и метаданные.

Тело content.xml формируется через ЗаписьXML в файл, затем контейнер собирается ЗаписьZipФайла.

 

Дедупликация стилей

Стиль ячейки в файле определяется её фактическим оформлением — шрифтом, фоном, рамками, выравниванием — и не зависит от содержимого. По свойствам ячейки вычисляется ключ; соответствие «ключ → имя стиля» обеспечивает один стиль на все одинаково оформленные ячейки документа. В файле собственной записи из сводного прогона (10 000 строк, документ с числами) — 11 ячеечных стилей против 80 132 у платформенной записи того же документа; файл на четверть меньше (76,0 МБ против 99,1 МБ на 50 тысячах строк — размеры обеих записей выводятся в таблице бенчмарка).

 

Чтение оформления агрегатными свойствами области

Поячеечное чтение свойств (десятки ячеек на строку) дорого — реализация с поячеечным разбором работала медленнее платформенной записи. Использованы агрегатные свойства области: запрошенное у области целиком свойство возвращает значение, когда оно одинаково у всех ячеек, и Неопределено — когда различается:

ОбластьСтроки = ТабДок.Область(НомерСтроки, 1, НомерСтроки, КоличествоКолонок);
Однородна = ОбластьСтроки.ЦветФона <> Неопределено
    И ОбластьСтроки.Шрифт <> Неопределено; // и ещё 6 агрегатов

Для однородно оформленных строк свойства читаются один раз с первой ячейки; поячеечный разбор остаётся только для строк с неоднородным оформлением.

 

Замеры

Собственная запись линейна при любом содержимом ячеек: 8,13–8,37 мс/строку на всех десяти точках сводного прогона. На малых размерах она дороже платформенной — выше постоянная стоимость строки (8,2 мс против 3,3 у платформы на 5 тысячах строк). С ростом документа платформенная запись дорожает, и между 25 и 30 тысячами строк кривые пересекаются; на 50 тысячах собственная запись быстрее платформенной в 2,7 раза (411,75 с против 1115,77).

Ограничение решения — стоимость чтения из табличного документа: агрегатное чтение свойств сканирует все ячейки области, и эта линейная по ширине строки цена платится за каждую строку. Ограничение снимается отказом от табличного документа — см. решение 2.

 

Решение 2: потоковая запись ODS непосредственно из данных

Для выгрузки табличный документ — промежуточная сущность: данные уже есть в выборке, и content.xml записывается напрямую из них, в том же цикле по выборке. Табличный документ остаётся только для XLSX.

 

Программный интерфейс из трёх функций

// До цикла: контекст из областей макета - шапка и имена колонок области "Строка"
Контекст = НачатьФайлODS(Макет.ПолучитьОбласть("Шапка"), Макет.ПолучитьОбласть("Строка"));

// В цикле по данным: соответствие "имя параметра колонки - значение"
ЗаписатьСтрокуODS(Контекст, ЗначенияСтроки);

// После цикла
ЗавершитьФайлODS(Контекст, ИмяФайла);
// при ошибке выгрузки - ОтменитьФайлODS(Контекст)

НачатьФайлODS выводит шапку из макета с оформлением, открывает временный content.xml через ФайловыйПоток и запоминает имена колонок. ЗаписатьСтрокуODS записывает одну строку таблицы. ЗавершитьФайлODS дописывает завершение и собирает контейнер. Стили строк известны заранее из области макета; дедупликация не требуется — в файле прямой записи из сводного прогона всего 2 ячеечных стиля.

 

Результат

Строка ODS записывается в общем проходе по данным, ячейки табличного документа не читаются вовсе; стоимость строки — последовательная запись XML-элементов в файловый поток. В сводном прогоне потоковая запись линейна (4,25–4,46 мс/строку), обгоняет платформенную уже между 5 и 10 тысячами строк, а на 50 тысячах быстрее её в 5,3 раза (212,26 с против 1115,77) и в 1,9 раза быстрее собственной записи из табличного документа (у той сверху стоимость чтения из документа).

 

Бенчмарк: воспроизведение замеров

К публикации приложена внешняя обработка. Она самодостаточна (не обращается к объектам конфигурации, открывается на любой базе) и воспроизводит ключевые эксперименты статьи на синтетическом макете 77 колонок. Все замеры ложатся в одну сводную таблицу и на один график — четыре линии на общих точках:

  1. Платформа (буквы) — вывод области макета с подстановкой параметров, числовые колонки заполнены буквенными строками: числоподобного содержимого в документе нет.
  2. Платформа (числа) — тот же способ вывода, тот же макет; единственное отличие — числовые колонки заполнены числами. Пара линий 1–2 — контролируемый эксперимент из раздела о причинах.
  3. Собственный писатель — запись того же документа с числами собственной процедурой с переносом оформления.
  4. Прямая запись — потоковая запись ODS из тех же данных без табличного документа.

Параметры: максимальный размер, число точек замера, длина строковых данных, каталог для файлов замера. Кнопка «Замерить все сценарии» выполняет все четыре линии последовательно; повторных замеров нет (собственный писатель замеряется один раз, на документе с числами). Результаты сохраняются в JSON.

Кроме секунд в таблице выводится удельная цена строки «мс/стр»: на графике абсолютного времени умеренная деградация неотличима от прямой, по удельной цене она видна сразу.

Сводный прогон, из которого взяты все цифры статьи (10 точек, максимум 50 000 строк), — на графике и на скриншоте формы ниже:

 

 

 

Выводы

  1. Причина нелинейной деградации платформенной записи ODS — числоподобное содержимое ячеек: типизированные числа и тексты вида «12345,67». Платформа создаёт таким ячейкам индивидуальные стили — практически по стилю на ячейку, — и стоимость записи растёт с размером документа: на сводном прогоне удельная цена строки выросла в 6,7 раза при увеличении документа в 10 раз. Способ формирования документа влияет только на постоянную стоимость строки.
  2. Запись XLSX тех же документов линейна: деградация — свойство именно записи ODS.
  3. Дедупликация стилей по фактическому оформлению делает собственную запись ODS линейной при любом содержимом (8,2 мс/строку на всех точках, 11 стилей в файле, файл на четверть меньше); ограничение — стоимость чтения из табличного документа.
  4. Для данной задачи, чтобы не обрабатывать ячейки табличного документа, применена потоковая запись content.xml непосредственно из данных — это экономит около половины времени относительно собственной записи из табличного документа. Решение не универсально: применимо, когда данные проходят через код выгрузки, а структура и оформление строк известны из макета; произвольный готовый табличный документ им не записать — для этого предназначена собственная запись из решения 1.

Замеры выполнены на платформе 8.3.27.1989.

Проверено на следующих конфигурациях и релизах:

  • 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.12.268

Вступайте в нашу телеграмм-группу Инфостарт

ODS OpenDocument ODF ТабличныйДокумент Записать производительность оптимизация выгрузка данных XLSX LibreOffice потоковая запись ЗаписьXML ЗаписьZipФайла стили ячеек замер производительности нагрузочное тестирование бенчмарк content.xml

См. также

Механизмы платформы 1С Программист Бесплатно (free)

Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?

16.07.2025    37331    TitanLuchs    109    

151

Механизмы платформы 1С WEB-интеграция Программист 1С:Предприятие 8 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    38353    dsdred    108    

154

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    33505    bayselonarrend    22    

179

HighLoad оптимизация Инструменты администратора БД Системный администратор Программист 1С 8.3 Абонемент ($m)

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих запросов на sql, ожиданий, конвертация запроса в 1С и рекомендации, где может тормозить.

10 стартмани

15.02.2024    23471    395    ZAOSTG    114    

129

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    33233    SeiOkami    48    

140

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    27847    YA_418728146    8    

175
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. infosoft-v 749 20.07.26 19:36 Сейчас в теме
Отличное исследование!
Вы же зарегистрировали ошибку на v8@1c.ru? Было бы здорово, если такой недостаток поправили бы в платформе.
2. Iotsuba 3 21.07.26 08:01 Сейчас в теме
(1) Спасибо, подал заявку на регистрацию ошибки.
Для отправки сообщения требуется регистрация/авторизация