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

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

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

В наличии

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

Категория:

Описание

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

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

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

 

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

has been added to your cart:
Оформление заказа