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

12.06.14

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

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

Скачать файл

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

Наименование По подписке [?] Купить один файл
Тестирование вариантов конкатенации
.epf 6,59Kb ver:1
23
23 Скачать (1 SM) Купить за 1 850 руб.

Во встроенном языке платформы 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 получились результаты идентичные методу массивом как на малых, так и на больших наборах подстрок. Поэтому я отдаю этому методы лавры победителя - при прочих равных он легко запоминается и не содержит подводных камней.

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

См. также

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

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

23.06.2024    7443    bayselonarrend    20    

154

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

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5942    dsdred    16    

80

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

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

24.01.2024    17666    YA_418728146    26    

71

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

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

11.12.2023    11222    dsdred    44    

130

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

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

06.10.2023    23757    SeiOkami    48    

135

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

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

14.09.2023    18828    human_new    27    

80

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

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

28.08.2023    14729    YA_418728146    7    

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

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

Раз существует более "навороченный" вариант с ЗаписьXML, то конечно стоит его рассмотреть и добавить в табличку сравнения быстродействия. Я думал и про этот объект, но не знал про его любопытный метод ЗаписатьБезОбработки() и потому не стал рассматривать. А вот от использования указанной в комменте реализации составления строки из массива я бы рекомендовал воздержаться - в ней есть баг, который я у себя дополнительно обошел (хотя в некоторых случаях искажение содержимого роли не играет и потому некоторым может подойти).
ildarovich; +1 Ответить
3. Dementor 1035 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 1061 15.06.19 13:44 Сейчас в теме
(1) ЗначениеВСтрокуВнутр - ошибочно излишне обрезает строку справа, в некоторых вариантах тестов.
Видимо вместо Массив.Количество() - надо что-то другое.. Разбираться не было времени, решил использовать ЗаписьXML.
4. Dementor 1035 13.06.14 15:07 Сейчас в теме
Статья и обработка обновлены четвертым способом конкатенирования строк.
6. Dementor 1035 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 1035 19.08.14 15:03 Сейчас в теме
(7) Улугбек, а на заборе написано, что Цой жив. И еще много чего тоже написано...
А попробуйте зайти в конфигуратор и воспользоваться этими функциями!

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

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