Формирование строки большой длины

19.04.20

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

Для опытных программистов в этой статье не будет ничего нового, но, возможно, кому-то статья сэкономит немного времени. Появилась у меня задача пройтись регулярными выражениями по наименованиям справочников. При подготовке строки в которой будут содержаться все наименования объектов справочника с соответствующими им ГУИДами, сразу обнаружил, что не все способы формирования строки одинаково быстро работают.

Сразу приведу пример с наиболее быстрым вариантом:

ИзвлеченныеТексты = Новый Массив;

Для Сч = 1 По Количество Цикл
	ИзвлеченныеТексты.Добавить("Мотороллер не мой.");
КонецЦикла;

Строка = СтрСоединить(ИзвлеченныеТексты, Символы.ПС);

Время выполнения кода в зависимости от количества повторений. В скобках указано время выполнения одной операции:

5 000 - 7 мс. (0.0014)

50 000 - 68 мс. (0.00136)

500 000 - 690 мс. (0.00138)

5 000 000 - 7 000 мс. (0.0014)

Сразу бросается в глаза линейный рост времени выполнения.

 

Почти полностью равный ему по производительности:

Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку(); 
	
Для Сч = 1 По Количество Цикл
	Запись.ЗаписатьБезОбработки("Мотороллер не мой.");
КонецЦикла;
	
Строка = Запись.Закрыть();	

Замеры производительности не привожу так как при заданных условиях результаты идентичные. Разница проявляется при конкатенации больших кусков текста. Тестировал на объединении строк размером примерно с эту статью и повторении в 500 000 раз. Первый способ оказался производительнее примерно на 10%. Остальные способы при таком варианте показали себя заметно хуже.

 

Альтернативный и менее производительный вариант:

Поток = Новый ПотокВПамяти();
ЗаписьТекста = Новый ЗаписьТекста(Поток);	
	
Для Сч = 1 По Количество Цикл
	ЗаписьТекста.ЗаписатьСтроку("Мотороллер не мой.");
КонецЦикла;
	
ЗаписьТекста.Закрыть();
ДД = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Строка = ПолучитьСтрокуИзДвоичныхДанных(ДД);

5 000 - 10 мс. (0.002)

50 000 - 100 мс. (0.002)

500 000 - 1 000 мс. (0.002)

5 000 000 - 10 000 мс. (0.002)

Рост времени выполнения так же линеен, но среднее время операции заметно больше. Данный вариант требует версии платформы не ниже 8.3.10.

 

Следующий вариант использует текстовый документ:

ТД = Новый ТекстовыйДокумент;

Для Сч = 1 По Количество Цикл
	ТД.ДобавитьСтроку("Мотороллер не мой.");
КонецЦикла;

Строка = ТД.ПолучитьТекст();

Так же время выполнения:

5 000 - 100 мс. (0.002)

50 000 - 1 500 мс. (0.03)

500 000 - 70 000 мс. (0.14)

Видно что время выполнения операции возрастает в зависимости от количества операций.

 

Ну и для интереса добавлю выполнение операции с использованием только строковой переменной:

Строка = "";

Для Сч = 1 По Количество Цикл
	Строка = Строка + "Мотороллер не мой." + Символы.ПС;
КонецЦикла;

500 - 2 мс. (0.004)

5 000 - 120 мс. (0.024)

50 000 - 57 000 мс. (1.14)

Заметен огромный рост выполнения одной операции уже на 50 тысячах повторений.

 

Так же рассмотрел интересный вариант из этой статьи:

мДД=Новый Массив;
мДД.Добавить(ПолучитьДвоичныеДанныеИзСтроки("Это"));
рДДДобавка=ПолучитьДвоичныеДанныеИзСтроки(" круто"));
Для й=1 По 100000 Цикл
	мДД.Добавить(рДДДобавка);
КонецЦикла;
а=ПолучитьСтрокуИзДвоичныхДанных(СоединитьДвоичныеДанные(мДД));

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

 

Рассмотрел способ из этой статьи:

Функция ВСтроку(Массив) Экспорт

    Возврат Сред(СтрЗаменить(ЗначениеВСтрокуВнутр(Массив), """}," + Символы.ПС + "{""S"",""", ""), 53 + СтрДлина(Формат(Массив.Количество(), "ЧГ=")), Массив.Количество())

КонецФункции

Он оказался медленнее варианта с потоками: процентов на 7 при конкатенации небольших строк и процентов на 30 при объединении больших кусков текста. Кстати второй способ был взят из комментария указанной статьи.

 

На этом всё. Спасибо за внимание.

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

большая строка конкатенация

См. также

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

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

16.07.2025    15291    TitanLuchs    99    

124

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

Про ООП в 1С и о том, как сделать свой код более кратким и выразительным при помощи использования текучего интерфейса (fluent interface).

03.02.2025    9874    bayselonarrend    126    

63

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

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

14.01.2025    15428    dsdred    77    

124

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

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

23.06.2024    17835    bayselonarrend    22    

168

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

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

13.03.2024    10109    dsdred    22    

84

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

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

24.01.2024    38009    YA_418728146    35    

75
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. berezdetsky 625 19.04.20 11:03 Сейчас в теме
Надеюсь в комментариях подскажут вариант кода достаточно быстродейственного для платформы ниже 8.3.10.

https://its.1c.ru/db/v8std#content:782:hdoc

Почему, кстати, 8.3.10? ПотокВПамяти появился вроде бы в 8.3.9.
MADCAT; kamisov; Redokov; +3 Ответить
2. MADCAT 12 20.04.20 06:22 Сейчас в теме
(1) , этот вариант даже быстрее, спасибо. Добавлю в публикацию.

А 8.3.10 так как ПолучитьСтрокуИзДвоичныхДанных появилось именно в этом релизе.
3. ImHunter 339 20.04.20 06:28 Сейчас в теме
А что насчет СтрСоединить() ?
4. MADCAT 12 20.04.20 08:38 Сейчас в теме
(3) Совершенно упустил для себя эту функцию. Пусть эта статья будет напоминанием моей невнимательности. Ну и возможно поможет кому то такому же невнимательному.
5. ImHunter 339 20.04.20 08:43 Сейчас в теме
(4) Так протестируйте. Вдруг ваш прием быстрее работает.
8. MADCAT 12 20.04.20 09:41 Сейчас в теме
(5) Протестировал и добавил.
6. PLAstic 296 20.04.20 08:43 Сейчас в теме
СтрШаблон тоже забыл.
7. plotnikov1c 34 20.04.20 09:18 Сейчас в теме
Я часто пользуюсь СтрРазделить(), СтрСоединить().
9. kamisov 223 26.04.20 11:13 Сейчас в теме
Меня всегда ЗаписьXML спасала. А вообще была статья про способы конкатенации и их сравнение: тык.
10. MADCAT 12 27.04.20 11:12 Сейчас в теме
(9) Добавил вариант с "ЗаписьXML". Отличный вариант.
Статья была, но там нет кода, нет варианта СтрСоединить и утверждается что методы "ЗаписьXML" и "ЗначениеВСтрокуВнутр" одинаковые по производительности.
11. kamisov 223 27.04.20 12:18 Сейчас в теме
(10)
утверждается что методы "ЗаписьXML" и "ЗначениеВСтрокуВнутр" одинаковые по производительности

Они одинаковые в пределах погрешности. Нельзя сравнивать производительность методов на динамических структурах, так как при каждом тесте они могут располагаться в очень разных участках памяти и от этого к частям этих структур будет разное время доступа. Суть всех этих статей: показать разность между стандартной конкатенацией (оператор +) и конкатенацией через объекты (ЗаписьXML, СтрСоединить и т.д.). Первый способ перезаписывает каждую итерацию строку в памяти полностью, остальные прописывают части строки в разных областях памяти, а потом при получении результата собирают все кусочки воедино. Если бы объекты выделяли огромный последовательный кусок памяти под данные (строку) и складывали бы туда эти данные последовательно - можно было бы говорить о сравнении методов. Но т.к. выделять большие объемы памяти под неопределенные размеры объектов - моветон, то используется схема указателей (ссылок), с дальнейшим сбором в единый контейнер (результат).
12. MADCAT 12 27.04.20 13:17 Сейчас в теме
(11) Неужели распределение в памяти единственный фактор влияющий на время выполнения процедуры? Тогда почему разные способы решения одной и той же задачи показывают примерно одинаковое соотношение времени выполнения на разных ПК? Мне просто очень везёт что время выполнения стабильно отличается в 3 раза?
13. kamisov 223 27.04.20 14:53 Сейчас в теме
(12) Да, видимо очень везет. Сервер тестовый, не нагруженный ничем? Потому что обычно даже самый простой запрос будет выполняться за разное время, +- несколько мс. А вообще да, способ расположения данных в памяти очень влияет на производительность. Существуют измерители скорости доступа к памяти, в которых обязательно имеются показатели последовательного чтения и случайного доступа. Последовательное чтение будет выполняться в разы быстрее случайного чтения. Это физика. Головка диска или указатель твердой памяти в случае последовательного чтения идет по конкретным координатам ОТ и ДО. В случае случайного чтения "прыгание" по диску/памяти происходит много раз, чем и вызывает снижение производительности.

Другими словами: копирование одного большого файла в 10ГБ (последовательное чтение) будет гораздо быстрее нежели копирование 100к файлов по 100КБ (ну примерно, прошу не придираться).
Оставьте свое сообщение