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

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 при объединении больших кусков текста. Кстати второй способ был взят из комментария указанной статьи.

 

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

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

См. также

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

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

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

11.03.2024    4481    dsdred    53    

71

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

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

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

24.01.2024    5282    YA_418728146    25    

63

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

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

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

11.12.2023    6401    dsdred    36    

111

1С-ная магия

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

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

06.10.2023    18466    SeiOkami    46    

118

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

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

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

14.09.2023    12082    human_new    27    

74

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

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

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

28.08.2023    8804    YA_418728146    6    

141

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

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

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

20.08.2023    6273    sebekerga    54    

94

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

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

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

27.06.2023    15974    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. berezdetsky 620 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 312 20.04.20 06:28 Сейчас в теме
А что насчет СтрСоединить() ?
4. MADCAT 12 20.04.20 08:38 Сейчас в теме
(3) Совершенно упустил для себя эту функцию. Пусть эта статья будет напоминанием моей невнимательности. Ну и возможно поможет кому то такому же невнимательному.
5. ImHunter 312 20.04.20 08:43 Сейчас в теме
(4) Так протестируйте. Вдруг ваш прием быстрее работает.
8. MADCAT 12 20.04.20 09:41 Сейчас в теме
(5) Протестировал и добавил.
6. PLAstic 295 20.04.20 08:43 Сейчас в теме
СтрШаблон тоже забыл.
7. plotnikov1c 33 20.04.20 09:18 Сейчас в теме
Я часто пользуюсь СтрРазделить(), СтрСоединить().
9. kamisov 150 26.04.20 11:13 Сейчас в теме
Меня всегда ЗаписьXML спасала. А вообще была статья про способы конкатенации и их сравнение: тык.
10. MADCAT 12 27.04.20 11:12 Сейчас в теме
(9) Добавил вариант с "ЗаписьXML". Отличный вариант.
Статья была, но там нет кода, нет варианта СтрСоединить и утверждается что методы "ЗаписьXML" и "ЗначениеВСтрокуВнутр" одинаковые по производительности.
11. kamisov 150 27.04.20 12:18 Сейчас в теме
(10)
утверждается что методы "ЗаписьXML" и "ЗначениеВСтрокуВнутр" одинаковые по производительности

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

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