Как известно в 1С со строковыми переменными часто приходится работать в режиме добавления строк в одну переменную.
Когда строка небольшой длины, все происходит достаточно быстро и можно работать вот так:
Строка1 = "Привет"; Строка2 = "мир!"; Результат = Строка1 + Строка2;
И все замечательно ровно до того момента, когда эти строки не становятся большими... Тогда скорость работы значительно падает.
Мы провели небольшие замеры производительности и выносим их на суд общественности.
Итак, смоделируем сначала условие задачи.
Задача
Необходимо написать функцию, которая возвращает в строковую переменную текст вида:
Это тестовая строка 1
Это тестовая строка 2
Это тестовая строка 3
...
Это тестовая строка N
Где N - число строк.
Разобрать несколько способов получения такой переменной.
Так же сделать график скорости работы в зависимости от N и сравнить получившиеся функции по производительности.
Решение
На самом деле, несмотря на вымышленность задания подобная задача в реальной жизни, в том или ином виде встречается сплошь и рядом. Есть большой цикл в котором мы результат складываем в текстовую переменную суммой нескольких строк. Так вот, было замечено, что для большого цикла и текста, время выполнения операции сложения строк растет нелинейно и для большого количества итераций не позволительно долго.
Где по оси Х у нас идет количество итераций, а по Y - время в миллисекундах.
Как видим, медленнее всего работает ТекстовыйДокумент:
Результат = Новый ТекстовыйДокумент; Для Индекс = 1 По КоличествоИтераций Цикл Результат.ДобавитьСтроку("Это тестовая строка " + Строка(Индекс)); КонецЦикла; Строка = Результат.ПолучитьТекст();
Затем у нас идет обычная работа со строкой:
Результат = ""; Для Индекс = 1 По КоличествоИтераций Цикл Результат = Результат + "Это тестовая строка " + Строка(Индекс) + Символы.ПС; КонецЦикла;
Далее по скорости идет работа с ПотокВПамяти + ЗаписьДанных:
Результат = Новый ПотокВПамяти; ЗаписьДанных = Новый ЗаписьДанных(Результат); Для Индекс = 1 По КоличествоИтераций Цикл ЗаписьДанных.ЗаписатьСтроку("Это тестовая строка " + Строка(Индекс)); КонецЦикла; ЗаписьДанных.Закрыть(); Строка = ПолучитьСтрокуИзДвоичныхДанных(Результат.ЗакрытьИПолучитьДвоичныеДанные());
Ну, а все остальные способы выполняются по времени примерно в одном диапазоне.
ПотокВПамяти + ЗаписьТекста
Как оказалось, со строками этот способ работает быстрее, чем ПотокВПамяти + ЗаписьДанных, хотя по идее, корни у них общие, в плане механизмов работы:
Результат = Новый ПотокВПамяти; ЗаписьТекста = Новый ЗаписьТекста(Результат); Для Индекс = 1 По КоличествоИтераций Цикл ЗаписьТекста.ЗаписатьСтроку("Это тестовая строка " + Строка(Индекс)); КонецЦикла; ЗаписьТекста.Закрыть(); Строка = ПолучитьСтрокуИзДвоичныхДанных(Результат.ЗакрытьИПолучитьДвоичныеДанные());
ЗаписьXML
ЗаписьXML, тоже работает быстро. Выглядит как какая-то магия:
Результат = Новый ЗаписьXML; Результат.УстановитьСтроку(); Для Индекс = 1 По КоличествоИтераций Цикл Результат.ЗаписатьБезОбработки("Это тестовая строка " + Строка(Индекс) + Символы.ПС); КонецЦикла; Строка = Результат.Закрыть();
Массив
В массив можно складывать строки и в конце использовать функцию СтрСоединить:
Результат = Новый Массив; Для Индекс = 1 По КоличествоИтераций Цикл Результат.Добавить("Это тестовая строка " + Строка(Индекс)); КонецЦикла; Строка = СтрСоединить(Результат, Символы.ПС);
Предварительные выводы
Если у вас строки не большой длины, то можно обойтись и простой суммой двух строковых переменных, вида: Строка1 + Строка2. Если строк достаточно, много то ни в коем случае не использовать работу с ТекстовымДокументом. Лучше выбрать что-то другое. Например, ПотокВПамяти + ЗаписьТекста. Это способ, который позволит работать с длинными строками как в памяти, так и из файла.
Почему при работе со строками разными методами, такой большой разброс по времени выполнения - вопрос и, на мой взгляд, самое удивительное в этом, что конкатенация обычных строк - это не самый быстрый способ сложения строк... Ну а какой из способов использовать - выбирать вам.
Прилагаем обработку, в которой можно поэкспериментировать введя свои значения итераций.
PS: Приготовьтесь, что ждать результата теста придется долго :)