Варианты конкатенации строк в 1С и замеры производительности.

12.06.14

Разработка - Механизмы платформы 1С

Практики использования типовых и самописных конфигураций 1С иногда сталкиваются с "торможениями" продуктов. Причины могут быть разными - некоторые любит делать множественные обращения через точку в циклах, другие используют вложенные запросы в параметрах виртуальных таблиц, третьи бессмысленно гоняют мегабайты контекста в клиент-серверной модели. Но иногда можно получить огромную потерю производительности на банальной операции сложения строк. Давайте рассмотрим эту ситуацию детальнее.

Скачать файлы

Наименование Файл Версия Размер
Тестирование вариантов конкатенации
.epf 6,59Kb
23
.epf 1 6,59Kb 23 Скачать

Во встроенном языке платформы 1С:Предприятие, как и во многих других языках программирования, присутствует возможность сложения строк. Это легко:

Переменная="Мама"+"мыла"+"Раму";

Когда же нужно из некоторой коллекции строк получить одну единую, то можно сделать в цикле:

Строка = Строка + ЭлементКоллекции;

Все это хорошо работает когда у нас немного данных. Но все кардинально меняется, когда счет строк идет на тысячи (обычное дело при работе с клиент-банками, веб-сервисами, КПК и в прочих ситуациях). Попробуйте и сами увидите как на глазах падает производительность. О резкой деградацию производительности при множественных конкатенациях уже писали. Даже на Инфостарте. Не говоря уже про обсуждения на партнерском форуме.

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

Некоторые предлагают очевидное в таком случае решение - использование текстового документа. С практической стороны необходимо отметить, что все составные строки в этом объекте идут отдельными строками. Т.е. воспользовавшись методом ПолучитьТекст() необходимо еще сделать замену переносов строк на пустую строку. В случае использования вами символа переноса строки в подстроках, необходимо предварительно сделать замену его на некоторую уникальную последовательность символов, а после получения результата произвести обратное преобразование.

Я же для себя изобрел собственный велосипед, который по скорости превзошел использование текстового документа. Все подстроки заносятся в массив, который перегоняется в текстовое представление с помощью ЗначениеВСтрокуВнутр(), а далее вычищается от "лишнего". Работает стабильно и довольно быстро. Подробности реализации можете посмотреть в прикрепленной обработке.

UPD 1. Из комментария узнал про новый способ конкатенирования - использование объекта ЗаписьXML. У него есть интересный метод ЗаписатьБезОбработки() для помещения уже готового документа в том виде, какой подается на вход, т.е. без лишних тегов.

Для того, что бы определить какой метод лучше (и стоило ли вообще заморачиваться) была написана маленькая обработка. Условия для всех равны - замер происходит в милисекундах от вызова серверной функции с реализацией соответствующего алгоритма до получения отклика. Что бы нивелировать случайные факторы, я проводил по четыре замера и выводил в таблицу среднее значение.

В результате я получил следующую таблицу:

 

Попыток Обычная конкатенация Текстовым документом Масивом подстрок
1000

63

97 57
5000

327

353 185
10000

847

642 330
15000

4100

958 462
20000

8672

1299 656

В результате мы еще раз убедились в непрактичности использования обычной конкатенации на больших объемах строк. Как видно из получившегося графика зависимость скорости выполнения от количества элементов имеет экспоненциальный характер. В то время, как оба метода "обхода" стабильно показывают прямолинейную зависимость. Что позволяет нам прогнозировать общее время выполнения обработок связанных с обработкой текста. И мой метод превосходит по быстродействию использование текстового документа в 2 разаCool

UPD 2. К сожалению не нашел в инфостартовском редакторе инструмента для редактирования количества столбцов таблицы и не увидел переключения в режим HTML-документа для правки руками. По результатам тестирования метода с ЗаписьXML получились результаты идентичные методу массивом как на малых, так и на больших наборах подстрок. Поэтому я отдаю этому методы лавры победителя - при прочих равных он легко запоминается и не содержит подводных камней.

строки конкатенация

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4531    dsdred    53    

72

Как готовить и есть массивы

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

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5294    YA_418728146    25    

63

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6410    dsdred    36    

112

1С-ная магия

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

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

06.10.2023    18475    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

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

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12088    human_new    27    

74

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8822    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

20.08.2023    6279    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    15986    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. ildarovich 7850 13.06.14 06:11 Сейчас в теме
Странно, но в статье Опять двойка, на которую автор ссылается, уже приводился предлагаемый здесь метод. Даже код уже был приведен
Функция ВСтроку(Массив) Экспорт
    Возврат Сред(СтрЗаменить(ЗначениеВСтрокуВнутр(Массив), """}," + Символы.ПС + "{""S"",""", ""), 53 + СтрДлина(Формат(Массив.Количество(), "ЧГ=")), Массив.Количество())
КонецФункции

Также в комментарии http://forum.infostart.ru/forum24/topic75023/message908183/#message908183 к той статье приведен еще более быстрый (на 12%) метод за авторством speshuric с использованием объекта ЗаписьXML.
2. Dementor 1015 13.06.14 12:10 Сейчас в теме
(1) ildarovich, все возможно. Но финт со ЗначениеВСтрокуВнутр() я придумал для своей обработки работы с веб-сервисом, которая до этого очень медленно работала. После этого я решил сравнить её быстродействие с "классикой" и способом, который нашел на партнерском форуме. А уже затем я решил поделится с общественностью своей наработкой. Про статью "Опять двойка" узнал в процессе верстки своей, так же как и про другие отдаленно похожие заметки (на других ресурсах). От мысли писать свою статью я не отказывался по причинам: она оригинальная, не повторяет чужих идей, приведены конкретные цифры замеров производительности в то время, когда другие лишь мимолетом упоминали про свои субъективные ощущения.

Раз существует более "навороченный" вариант с ЗаписьXML, то конечно стоит его рассмотреть и добавить в табличку сравнения быстродействия. Я думал и про этот объект, но не знал про его любопытный метод ЗаписатьБезОбработки() и потому не стал рассматривать. А вот от использования указанной в комменте реализации составления строки из массива я бы рекомендовал воздержаться - в ней есть баг, который я у себя дополнительно обошел (хотя в некоторых случаях искажение содержимого роли не играет и потому некоторым может подойти).
ildarovich; +1 Ответить
3. Dementor 1015 13.06.14 14:40 Сейчас в теме
(1) ildarovich, про 12% - полное вранье. Добавил в обработку тестирование ЗаписиXML - результаты сопоставимы с методом массива почти на 99%!!! Так на формирование строки из 50000 подстрок методом массива уходит 1466 милисекунда, а с помощью ЗаписиXML - 1474. При работе со 100000 подстрок результаты - 2906 и 2985. Единственное преимущество - элегантность кода и отсутствие шаманства.
13. SlavaKron 22.02.17 17:46 Сейчас в теме
(1) Следует исправить на:
Сред(СтрЗаменить(ЗначениеВСтрокуВнутр(Массив), """}," + Символы.ПС + "{""S"",""", ""), 53 + СтрДлина(Формат(Массив.Количество(), "ЧГ=")))

Вы из строки берете количество символов, равное количеству элементов массива.
14. Lapitskiy 1057 15.06.19 13:44 Сейчас в теме
(1) ЗначениеВСтрокуВнутр - ошибочно излишне обрезает строку справа, в некоторых вариантах тестов.
Видимо вместо Массив.Количество() - надо что-то другое.. Разбираться не было времени, решил использовать ЗаписьXML.
4. Dementor 1015 13.06.14 15:07 Сейчас в теме
Статья и обработка обновлены четвертым способом конкатенирования строк.
6. Dementor 1015 19.08.14 13:55 Сейчас в теме
(5) infostart user, это не способ, а всего лишь анонс будущей функциональности. Как показывает практика, самый короткий промежуток между заметкой в зазеркалье и получением тестовой сборки платформы равен полугоду. Скорее всего добавят в 8.3.6
wowik; Bukaska; +2 Ответить
7. Улугбек 19.08.14 13:26 Сейчас в теме
Как говорится - в 8-ке это реализовано:

http://v8.1c.ru/o7/201408str/index.htm

Функция форматирования СтрШаблон()
Функция работы со строками СтрСравнить()
Функции работы со строками СтрНачинаетсяС(), СтрЗаканчиваетсяНа()
Функции работы со строками СтрРазделить(), СтрСоединить()
Функция работы со строками СтрНайти()
8. Dementor 1015 19.08.14 15:03 Сейчас в теме
(7) Улугбек, а на заборе написано, что Цой жив. И еще много чего тоже написано...
А попробуйте зайти в конфигуратор и воспользоваться этими функциями!

Подсказка: в ЗАЗЕРКАЛЬЕ пишут разработчики платформы о новых фичах, которые они у себя разрабатывают. Это не место для официальных пресс-релизов, а всего лишь блог. После разработки пройдет еще цикл тестирования и по результатам примут решение, когда переносить их в рабочие сборки.
9. Улугбек 19.08.14 14:07 Сейчас в теме
10. CheBurator 3119 20.08.14 18:15 Сейчас в теме
После разработки пройдет еще цикл тестирования и по результатам примут решение, когда переносить их в рабочие сборки.

вау, там у них есть тестирование? мы перестанем чувстовать себя подопытными кроликами? наконец-то!
11. Dementor 1015 20.08.14 19:58 Сейчас в теме
(10) CheBurator, разве можно быть настолько доверчивым?
Людям свойственно ошибаться, даже при тестировании на наличие ошибок :)
12. with 20.08.14 21:00 Сейчас в теме
ИМХО
1) 1С генерирует не исполняемый код, в всего лишь строит объектную модель, которая потом исполняется в виртуальной машине.
2) Такие типы интерпретаторов не предназначены для большого количества вычислений, которые требуют скорости работы. Написанный код на 1С всегда уступит по скорости реализации на с++. Это надо понимать, и не ждать чудес.
Ну и последнее, приведенные примеры работают быстрее, потому что там строки создаются и обрабатываются на уровне одного объекта, написанного на с++ и 1С там только дергает системные ф-ции.
Оставьте свое сообщение