Скорость сложения строк большой длины в 1С разными методами (конкатенация строк)

Публикация № 1577532 02.01.22

Приемы и методы разработки - Практика программирования

обработка замер производительности график производительность конкатенация строки сложение

Как известно, в 1С со строковыми переменными часто приходится работать в режиме добавления строк в одну переменную. Когда строка небольшой длины, все происходит достаточно быстро и можно работать вот так: Строка1 = "Привет"; Строка2 = "мир!"; Результат = Строка1 + Строка2; И все замечательно ровно до того момента, когда эти строки не становятся большими... Тогда скорость работы значительно падает. Я провел небольшие замеры производительности и выношу их на суд общественности.

Итак, смоделируем сначала условие задачи.

Задача

Необходимо написать функцию, которая возвращает в строковую переменную текст вида:

Это тестовая строка 1
Это тестовая строка 2
Это тестовая строка 3
...
Это тестовая строка N

Где N - число строк.
Разобрать несколько способов получения такой переменной.
Так же сделать график скорости работы в зависимости от N и сравнить получившиеся функции по производительности.

Решение

На самом деле, несмотря на вымышленность задания подобная задача в реальной жизни, в том или ином виде встречается сплошь и рядом. Есть большой цикл в котором мы результат складываем в текстовую переменную суммой нескольких строк. Так вот, было замечено, что для большого цикла и текста, время выполнения операции сложения строк растет нелинейно и для большого количества итераций не позволительно долго.

Где по оси Х у нас идет количество итераций, а по Y - время в миллисекундах.

1. ТекстовыйДокумент. Как мы видим, этот способ работает медленнее всего:

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

2. Строка. Затем у нас идет обычная работа со строкой:

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

3. Шаблон. Интересный предложение по реализации от coollerinc. Отнесся к этому методу скептически изначально, т.к. работа со строками никуда не девается, но ради чистоты эксперимента, добавил тест.

Результат = "";
Шаблон = "%1 %2";
Для Индекс = 1 По КоличествоИтераций Цикл
	Результат = СтрШаблон(Шаблон, Результат, "Это тестовая строка " + Строка(Индекс) + Символы.ПС);
КонецЦикла;

Как я и ожидал, результат не очень... После 10000 итераций способ становится самым медленным (на скриншоте этого не видно, но по факту это так). 

4. Далее по скорости идет работа с ПотокВПамяти + ЗаписьДанных:

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

5. ПотокВПамяти + ЗаписьТекста. Как оказалось, со строками этот способ работает быстрее, чем ПотокВПамяти + ЗаписьДанных, хотя по идее, корни у них общие, в плане механизмов работы:

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

6. ЗаписьXML, тоже работает быстро. Выглядит как какая-то магия:

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

7. Массив. В массив можно складывать строки и в конце использовать функцию СтрСоединить:

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

8. ЗаписьJSON, работает быстро. Спасибо Rustig, который подсказал добавить и такой вариант для тестирования.

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

Изначально было подозрение, что это будет работать быстрее чем ЗаписьXML, но это оказалось не так. Тесты показывают примерно одинаковое время работы с вариантом 6. Видимо все дело в том, что есть общие механизмы в реализации этих объектов платформы и, видимо, реализация метода ЗаписатьБезОбработки одинаковая.

9. ПотокВПамяти + ЗаписьТекста + начальное выделение памяти под поток. Думалось, что это хороший вариант для тех случаев, когда изначально известен размер данных. Спасибо Perfolenta.

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

Длину строки умножаем на 16 накинул на кодировку в UTF-8 и на количество итераций. Получаем примерный размер для потока. Именно примерный. В таки у нас эксперимент и выделенного размера должно быть достаточно. Но оказалось, что по скорости, что с выделением начального объема памяти, что без выделения, все работает примерно одинаково. В комментариях к статье есть мои размышления на эту тему в сторону Capacity.

Замечания и оговорки

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

Предварительные выводы

Если у вас строки не большой длины, то можно обойтись и простой суммой двух строковых переменных, вида: Строка1 + Строка2. Если строк достаточно, много то ни в коем случае не использовать работу с ТекстовымДокументом. Лучше выбрать что-то другое. Например, ПотокВПамяти + ЗаписьТекста. Это способ, который позволит работать с длинными строками как в памяти, так и из файла.

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

Тестировалось на платформе 8.3.19.1264

PS: Приготовьтесь, что ждать результата теста придется долго :)

PPS: В процессе написания обработки были использованы публикации:

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

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

Скачать файлы

Наименование Файл Версия Размер
Обработка тестирования конкатенации строк разными способами

.epf 8,57Kb
1
.epf 8,57Kb 1 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. coollerinc 150 02.01.22 20:42 Сейчас в теме
Можно еще вариант проверить:

Результат = "";
Шаблон = "1% 2% 
|";
Для Индекс = 1 По КоличествоИтераций Цикл
 
Результат = СтрШаблон(Шаблон, Результат ,  "Это тестовая строка " + Строка(Индекс) );

КонецЦикла;



Обычную работу со строкой(Результат = Результат + "Это тестовая строка " + Строка(Индекс) + Символы.ПС;), когда большие строки и несколько слогаемых, лучше не использовать. Фактически это интерпретируется примерно так:

ПромежуточныйРезультат1 = Результат + "Это тестовая строка ";
ПромежуточныйРезультат2 = ПромежуточныйРезультат1 + Строка(Индекс) ;
Результат = ПромежуточныйРезультат2 + Символы.ПС;

Это одновременно в нескольких переменных хранится почти одно и тоже, что отжирает память.
DrAku1a; bulpi; Созинов; tormozit; +4 Ответить
6. Diversus 2232 03.01.22 13:29 Сейчас в теме
(1)
Обычную работу со строкой(Результат = Результат + "Это тестовая строка " + Строка(Индекс) + Символы.ПС;), когда большие строки и несколько слогаемых, лучше не использовать. Фактически это интерпретируется примерно так:

ПромежуточныйРезультат1 = Результат + "Это тестовая строка ";
ПромежуточныйРезультат2 = ПромежуточныйРезультат1 + Строка(Индекс) ;
Результат = ПромежуточныйРезультат2 + Символы.ПС;

Это одновременно в нескольких переменных хранится почти одно и тоже, что отжирает память.


Проверил ваш вариант. Он на графике фиолетовый.
Уступает вообще всем вариантам на больших значениях итераций. Чуть-чуть его видоизменил:

Результат = "";
Шаблон = "%1 %2";
Для Индекс = 1 По КоличествоИтераций Цикл
	Результат = СтрШаблон(Шаблон, Результат, "Это тестовая строка " + Строка(Индекс) + Символы.ПС);
КонецЦикла;
Прикрепленные файлы:
the1; mrChOP93; coollerinc; +3 Ответить
2. Rustig 1408 03.01.22 09:59 Сейчас в теме
1. Для истории обсуждения оставлю ссылку на последовательное чтение и запись файлов через Потоки https://wonderland.v8.1c.ru/blog/novye-instrumenty-dlya-raboty-s-dvoichnymi-dannymi-obespechivayut-kak-posledovatelnyy-dostup-k-danny/?sphrase_id=268058

Вот здесь было обсуждение - продолжение темы потоков ЧтениеДанных и ЗаписьДанных. Работа со строками

2. Запись в json насколько быстрее записи в xml? Мне кажется, запись в джейсон должна быть быстрее.

3. Использование смешанных технологий - частями собираем тексты, абзацы, параграфы, блоки в цикле, затем последовательно их соединяем в промежуточные строки (или сразу в итоговую строку), затем промежуточные строки собираем в итоговую строку.

4. Работу со строками можно также увидеть и проанализировать в технологии обменов - для транспорта собирается не один большой файл, а несколько небольших файлов - стоит проверка на количество отправляемых данных - один файл формируется , например, только для не более 1000 объектов. То есть все понимают, что собрать и отправить файл большего размера - это значит столкнуться с другими проблемами на каждом шаге - сборка большого файла, отправка по интернету, далее чтение большого файла....На каждом шаге есть свои ограничения... Поэтому возможно лучше в цикле собрать несколько файлов, а не один итоговый....И будет быстрее.

5. Как прочитать и обойти весь справочник Номенклатура? Можно через запрос, и получить "нехватку памяти", а можно через объектную модель Выборка = Справочники.Номенклатура.Выбрать(); Пока Выборка.Следующий() Цикл....
Собственно ограничения заложены изначально, поэтому обход цикла и сборка файла должны проходить с пониманием ограничений - на твоем компе какое железо? тот же самый алгоритм на моем ноуте будет работать в два раза медленнее и вылетит в ошибку нехватки памяти...

6. Современные технологии позволяют распараллелить вычисления Параллельные вычисления
Задача собрать строку - хорошо распараллеливается: ИтоговаяСтр = Стр1 + Стр2 + Стр3
- полагаю, выигрыш может быть положительный.
CratosX; rusmil; +2 Ответить
3. Cmapnep 14 03.01.22 10:07 Сейчас в теме
Плюсанул, но раз уж речь о больших данных, то напрашивается еще и сравнение по используемой памяти!
dhurricane; +1 Ответить
4. Diversus 2232 03.01.22 13:20 Сейчас в теме
(2) При чем здесь запись в JSON и XML? Или выборка из справочника Номенклатура? Я не совсем понимаю при чем здесь это?
В статье, я пытаюсь решить классическую задачу с которой сталкивается каждый, а именно: работа со строками большой длины, в цикле с формированием большого текста. Это может быть большой HTML-документ (я в курсе про DOM-модель и про его формирование другим способом), большой какой-то текстовый файл и его обработка, или в большом цикле работа со строками и т.д. и т.п. Мое "микро-исследование" про влияние размера строк на скорость работы.
Понятно, что от компьютера к компьютеру скорость работы будет отличаться, но я думаю, что график работы как раз для этого случая. Он позволяет увидеть общую тенденцию. Как пример: на больших строках самый медленный - это ТекстовыйДокумент. Это будет так хоть на мощном компьютере, хоть на "дохлом" ноуте.
Теперь о конструктиве. По п.6 надо подумать как это втиснуть в текущий тест.
(3)
Плюсанул, но раз уж речь о больших данных, то напрашивается еще и сравнение по используемой памяти!

Замер используемой памяти? Хм. Когда в 1С появился профилировщик памяти? ТЖ, насколько я знаю, позволяет включить мониторинг утечек памяти, но здесь то утечек памяти нет, да и моментом очистки памяти разработчик в явном виде управлять не может. Включить и выключить мониторинг потребляемой памяти для конкретной процедуры в 1С, опять же, на сколько я знаю, такой возможности нет. Если ошибаюсь и это возможно, то поправьте меня пожалуйста. Был бы признателен. Спасибо.
5. Rustig 1408 03.01.22 13:29 Сейчас в теме
(4)
При чем здесь запись в JSON и XML?


в твоем микро-исследовании ты написал:

2. ЗаписьXML, тоже работает быстро. Выглядит как какая-то магия:

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


Хотелось бы увидеть разницу с записью в джейсон. Есть предположение, что магия будет интересней.
Особенно при записи текста для html-страницы.
8. Diversus 2232 03.01.22 13:44 Сейчас в теме
(5)
Хотелось бы увидеть разницу с записью в джейсон. Есть предположение, что магия будет интересней.

Замысел понял.
Проверил, примерно одинаково работают. Причем где-то дольше XML, где-то JSON на 1-2 единицы. Так что примерно равны по скорости. Как я понимаю, равенство потому, что используется метод ЗаписатьБезОбработки и там и там. А т.к. скорее всего внутри ЗаписьXML и ЗаписьJSON имеют в реализации общего класса-предка, который с записанными строками без обработки работает одинаково.

Проверяемый блок кода:
Результат = Новый ЗаписьJSON;
Результат.УстановитьСтроку();
Для Индекс = 1 По КоличествоИтераций Цикл
	Результат.ЗаписатьБезОбработки("Это тестовая строка " + Строка(Индекс) + Символы.ПС);
КонецЦикла;	
Строка = Результат.Закрыть();
Прикрепленные файлы:
CratosX; the1; +2 Ответить
7. Rustig 1408 03.01.22 13:42 Сейчас в теме
(4)
выборка из справочника Номенклатура?

В платформе 1с имеются известные способы обхода нехватки памяти и ускорения обхода цикла для большого массива данных. Простой и показательный пример со справочником Номенклатура - об этом также на ИТС написано - не держать в памяти весь массив данных, а последовательно его считывать - это обычная практика работы с большими массивами данных.
Задача записи длинной строки (которая формируется в цикле) - делится собственно на две -
1) откуда и как берутся сведения (данные) - как раз я привел пример как можно ускорить в целом алгоритм
2) как записывать в строку - последовательно или кучей - как раз это и есть та классическая задача, с которой ты начал.

Еще раз, скорость прохождения алгоритма для Записи строки (любой вариант возьми) по справочнику Номенклатура будет разным для случая обхода через объектную модель и через Запрос по всему справочнику и дальнейшему обходу по результату выполнения запроса....

В общем разная скорость сначала считывания данных, и скорость записи в строку - для определенного варианта постоянна. Итоговая скорость разная...
Diversus; +1 Ответить
9. Diversus 2232 03.01.22 13:54 Сейчас в теме
(7) Мысль понял. Спасибо.
И кстати, если обратить внимание на скриншоты в публикации и в форуме, то можно заметить разницу между скоростью работы со строками и текстовым документом.
В публикации самый медленный ТекстовыйДокумент, а потом Строки, а в форуме уже самые медленные Строки, а потом ТекстовыйДокумент.
Дело в том, что публикацию я писал на работе, а там стоит компьютер на AMD Ryzen 3700 + 32 Гб ОЗУ, а в форуме я отвечаю на компьютере Intel Core-i5 9600К + 32 Гб. Отсюда такая разница. Интересно, почему такой разброс на машинах с разной архитектурой...
10. gzharkoj 419 04.01.22 11:18 Сейчас в теме
(9) Может потому, что память на разной частоте работает.
11. Perfolenta 198 04.01.22 11:36 Сейчас в теме
В целом результаты соответствуют обычной житейской логике... что бы сложить две строки надо выделить кусок памяти равный сумме длин строк и скопировать в него обе строки... по мере роста одной из них, время её копирования растет, что делает процесс не линейным, а так же приводит к фрагментации памяти...
Соответственно, предварительно накапливая строки, мы получаем возможность выделить память один раз и скопировать все строки в итоговую за один проход... общее выделение памяти будет больше, а фрагментация меньше...
Можно попробовать ещё вариант через ПотокВПамяти, но не так как у автора, а с предварительным выделением памяти под суммарную длину строк, если длина всех строк заранее известна... дело в том, что если заранее не указать необходимый размер потока, то в игру вступает внутренняя логика автоматического увеличения размера буфера при добавлении данных, что ведет к дополнительным расходам...
С текстовым документом особая история, т.к. внутри себя, при добавлении строки он скорее всего сканирует её на предмет наличия разделителей строки...
12. Diversus 2232 04.01.22 14:24 Сейчас в теме
(11)
Можно попробовать ещё вариант через ПотокВПамяти, но не так как у автора, а с предварительным выделением памяти под суммарную длину строк, если длина всех строк заранее известна... дело в том, что если заранее не указать необходимый размер потока, то в игру вступает внутренняя логика автоматического увеличения размера буфера при добавлении данных, что ведет к дополнительным расходам...

Провел тест и ничего особо не меняется при назначении сразу нужного объема.
Скорее всего там все обстоит точно так же, как и в других ЯП с подобными структурами. Насколько я знаю есть несколько стратегий работы с памятью с использованием Capacity (емкость), которую не надо путать с размером.
Грубо говоря, Capacity - это объем сколько занимает память под объект, когда реальный размер занимаемых данных полностью заполнен этот объем увеличивается. Причем не на 1, а сразу в 2 раза, или как-то еще.
Таким образом, ПотокВПамяти не перераспределяет память каждый раз, когда что-то вставляется, а только тогда, когда дополнительная память исчерпана.
Пример как оно работает в других ЯП (схематично): Пусть начальное количество элементов в массиве - 0, начальное значение Capacity массива - 8, и размер одного элемента 1 байт (для простоты).
Теперь в цикле мы добавляем по 1 элементу в массив. Как только количество элементов станет равным 8, Capacity (емкость) увеличится до 16, как только количество элементов станет 16, Capacity увеличится до 32, когда дойдет до 32, произойдет увеличение и выделение памяти сразу под 64 элемента и т.д.
Такой подход позволяет достаточно быстро увеличить емкость массива и на больших массивах перераспределение памяти будет происходить не часто. При этом память будет использоваться достаточно экономно.
Понятно, это всего лишь пример. В реальной жизни увеличение Capacity может быть не на 2, а на 1.5 или еще как-то, как решат разработчики. Да и вообще там все несколько сложнее, на самом деле :)

Использовал код:
Результат = Новый ПотокВПамяти(КоличествоИтераций * 16 * (СтрДлина("Это тестовая строка ") + 4)); // UTF
ЗаписьТекста = Новый ЗаписьТекста(Результат);
Для Индекс = 1 По КоличествоИтераций Цикл
	ЗаписьТекста.ЗаписатьСтроку("Это тестовая строка " + Строка(Индекс));
КонецЦикла;
ЗаписьТекста.Закрыть();
Строка = ПолучитьСтрокуИзДвоичныхДанных(Результат.ЗакрытьИПолучитьДвоичныеДанные());
Показать
Прикрепленные файлы:
13. Perfolenta 198 04.01.22 19:23 Сейчас в теме
(12) дело в том, что используемый код сам слишком медленный, что бы заметить эффекты от изменения метода выделения памяти...
например, если избавиться от лишних итераций цикла, то сразу можно получить большой выигрыш:
КоличествоИтераций=100000;	

Стр="";
Для Индекс = 1 По 1000 Цикл
    Стр=Стр+"Ф";
КонецЦикла;

т=ТекущаяУниверсальнаяДатаВМиллисекундах();
Результат = Новый ПотокВПамяти(КоличествоИтераций * 16 * (СтрДлина(Стр) + 4)); // UTF
ЗаписьТекста = Новый ЗаписьТекста(Результат);
Для Индекс = 1 По КоличествоИтераций/10 Цикл
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
    ЗаписьТекста.ЗаписатьСтроку(Стр);
КонецЦикла;
ЗаписьТекста.Закрыть();
Строка = ПолучитьСтрокуИзДвоичныхДанных(Результат.ЗакрытьИПолучитьДвоичныеДанные());	
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах()-т);


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

Показать
15. Perfolenta 198 05.01.22 05:37 Сейчас в теме
(12) Кстати, интересно, когда я запускаю этот код на 1С, то версия с предварительным выделением памяти почему-то работает чуть-чуть медленнее, чем с автоматическим выделением... примерно на 7%... это странно, ведь казалось бы, должно быть наоборот...
Когда же я запускаю этот же код на своей Перфоленте, то версия с предварительным выделением памяти работает быстрее в среднем на 11%, как и предполагалось...
Ещё одна странность, я просто копипастил Ваш код, но у меня в 1С ТекстовыйДокумент работает значительно быстрее, чем простая конкатенация строк, Не так уж и много отставая от потоков... возможно это зависит от версии платформы...
И ещё, в Вашем коде для простой конкатенации можно сделать одно маленькое улучшение, значительно увеличивающее производительность, надо всего-лишь взять часть выражения в скобки:
Результат = "";
Для Индекс = 1 По КоличествоИтераций Цикл
    Результат = Результат + ("Это тестовая строка " + Строка(Индекс) + Символы.ПС);
КонецЦикла;
Diversus; +1 Ответить
16. Diversus 2232 05.01.22 12:53 Сейчас в теме
(15)
И ещё, в Вашем коде для простой конкатенации можно сделать одно маленькое улучшение, значительно увеличивающее производительность, надо всего-лишь взять часть выражения в скобки

Да! По правилам то, что в скобках вычисляется первым, а потом добавить к большой строке одной строкой, а если без скобок, то все подстроки добавляются к большой строке по очереди, что при работе с большими строками будет медленней. Отличное предложение.
29. Darklight 27 10.01.22 13:08 Сейчас в теме
(16)Ну, для чистоты эксперимента - наверное во всех тестах надо было бы сначала сформировать добавляемую строку в отдельной переменной - а уже потом ей конкатенировать в общую.
Или вообще остановиться на конкатенации константной строки - чтобы исключить затраты времени на её формирование!
Но замечание, безусловно, архиполезное - но существенное только для прямой конкатенации строк!
14. ivanov660 2908 04.01.22 23:09 Сейчас в теме
Можно было бы табличку с позициями нарисовать, по картинкам некоторые цвета сливаются и тяжело воспринимается.
17. Идальго 201 05.01.22 23:16 Сейчас в теме
Может дело в особенностях строкового типа и его хранения в памяти(в куче)? Былож что-то такое, ну, типа оно в куче каждый раз создает новую переменную (равную предыдущей плюс приконкатенированная часть) - и так, для каждой итерации цикла. В результате, получается неэффективное использование памяти.
18. DrAku1a 1471 07.01.22 11:46 Сейчас в теме
Интересная тема. После статьи "Самый быстрый FizzBuzz на 1С" считал, что через массив - самый быстрый вариант, и уж точно быстрее, чем сложение строк.
Для чистоты эксперимента, стоило бы проверить такой вариант:
Переменная1 = "Это тестовая строка 1";
Переменная2 = "Это тестовая строка 2";
...
Переменная1000 = "Это тестовая строка 1000";

//***начать отсчет времени ***

МассивСтрок = новый Массив();
МассивСтрок.Добавить(Переменная1);
МассивСтрок.Добавить(Переменная2);
...
МассивСтрок.Добавить(Переменная1000);
Строка = СтрСоединить(МассивСтрок, Символы.ПС);

//*** Закончить замер времени ***

Сообщить(Строка);
Показать
ardn; Rustig; +2 Ответить
19. Rustig 1408 09.01.22 15:57 Сейчас в теме
(0)
7. Массив. В массив можно складывать строки и в конце использовать функцию СтрСоединить:

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

А что если рассмотреть строку как небольшую "книгу"?
Книга - это двумерный массив (n,m) - где n - количество страниц, m - количество строк на странице
сначала собираем книгу цикл в цикле, затем цикл в цикле обращаемся к СтрСоединить страница за страницей...
Кол-во строк = 1000 ? тогда книгу можно представить как 20-ть страниц по 50 строк....

Если подобная задача касалась бы разметки html-страницы, я бы еще попробовал использовать Соответствие, ключами которого были бы условно говоря <заголовок1><тело1><что-то еще>, а значениями были бы как раз-таки строки... это для простой html-страницы...

для сложной html-страницы попробовал бы использовать структуру + массивы - как раз по подобию древовидной структуры json https://infostart.ru/public/1573208/
21. Darklight 27 10.01.22 09:47 Сейчас в теме
(19)Данному варианту явно не хватает подварианта с заранее выделенной памятью под массив - что важно для очень больших массивов:
Результат = Новый Массив(КоличествоИтераций);
Для Индекс = 0 По КоличествоИтераций-1 Цикл
Результат[Индекс] = "Это тестовая строка " + Строка(Индекс+1));
КонецЦикла;
Строка = СтрСоединить(Результат, Символы.ПС);
33. Rustig 1408 10.01.22 22:41 Сейчас в теме
(21)
вот код 4-х примеров (сценариев алгоритма)
Старт = ТекущаяДата();
	
	//первый пример
	Результат = "";
	Для Индекс = 1 По КоличествоИтераций Цикл
		Результат = Результат + "Это тестовая строка " + Строка(Индекс) + Символы.ПС;
	КонецЦикла;
	
	Стоп = ТекущаяДата();
	Сообщить(Стоп - Старт);
	
	//второй пример
	Старт = ТекущаяДата();
	
	КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок); 	
	Книга = Новый Массив; 	
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга.Добавить(Страница);  		
	КонецЦикла;
	
	//Результат = СтрСоединить(Книга, Символы.ПС);
	Результат = "";
	Для Индекс = 0 По КолСтраниц-1 Цикл
		Результат = Результат + Книга.Получить(Индекс);		
	КонецЦикла;	
	
	Стоп = ТекущаяДата();
	Сообщить(Стоп - Старт);
	
	//третий пример
	Старт = ТекущаяДата();
	
	Книга = Новый Массив(КолСтраниц);
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга.Добавить(Страница); 		
	КонецЦикла;
	
	//Результат = СтрСоединить(Книга, Символы.ПС);
	Результат = "";
	Для Индекс = 0 По КолСтраниц-1 Цикл
		Результат = Результат + Книга.Получить(Индекс);		
	КонецЦикла;
	
	Стоп = ТекущаяДата();
	Сообщить(Стоп - Старт);
	
	//четвертый пример
	Старт = ТекущаяДата();

	Книга = "";
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга = Книга + Страница; 		
	КонецЦикла;
	
	Стоп = ТекущаяДата();
	Сообщить(Стоп - Старт);

Показать


вот результат:
65
1
0
2

у меня нет функции СтрСоединить() - я ее заменил на обход массива
Прикрепленные файлы:
37. Darklight 27 11.01.22 09:20 Сейчас в теме
(33)Кто же через "ТекущаяДата()" замеры устраивает. Нужно использовать "ТекущаяУниверсальнаяДатаВМиллисекундах()"
С прямой конкатенацией строк уже выше (15) упомянули, что крайне важна скобочная оптимизация! В идеале (для чистоты замеров) - везде (во всех ваиантах) вынести это вычисление в отдельной переменной, которую уже конкатенировать разными способами (ну или просто использовать константную строку - для данного теста этого достаточно). А вы в последующих тестах вообще работали с готовыми строками!
И не понятно, зачем так всё усложнять?
38. Rustig 1408 11.01.22 09:41 Сейчас в теме
(37)
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	//первый пример
	Результат = "";
	Для Индекс = 1 По КоличествоИтераций Цикл
		Результат = Результат + ("Это тестовая строка " + Строка(Индекс) + Символы.ПС);
	КонецЦикла;
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
	
	//второй пример
	Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок); 	
	Книга = Новый Массив; 	
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + ("Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС); 			
		КонецЦикла;
		
		Книга.Добавить(Страница);  		
	КонецЦикла;
	
	//Результат = СтрСоединить(Книга, Символы.ПС);
	Результат = "";
	Для Индекс = 0 По КолСтраниц-1 Цикл
		Результат = Результат + Книга.Получить(Индекс);		
	КонецЦикла;	
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
	
	//третий пример
	Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Книга = Новый Массив(КолСтраниц);
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + ("Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС); 			
		КонецЦикла;
		
		Книга.Добавить(Страница); 		
	КонецЦикла;
	
	//Результат = СтрСоединить(Книга, Символы.ПС);
	Результат = "";
	Для Индекс = 0 По КолСтраниц-1 Цикл
		Результат = Результат + Книга.Получить(Индекс);		
	КонецЦикла;
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
	
	//четвертый пример
	Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();

	Книга = "";
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + ("Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС); 			
		КонецЦикла;
		
		Книга = Книга + Страница; 		
	КонецЦикла;
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);

Показать


Результат для 30 000 строк и 60 строк на страницу:
15 581
2 985
2 711
2 963
Прикрепленные файлы:
40. Rustig 1408 11.01.22 09:46 Сейчас в теме
(37)
Кто же через "ТекущаяДата()" замеры устраивает. Нужно использовать "ТекущаяУниверсальнаяДатаВМиллисекундах()"


для первого приближения и больших данных всегда можно использовать ТекущаяДата() - она покажет сравнительно и относительно разницу между алгоритмами.

(37)
С прямой конкатенацией строк уже выше (15) упомянули, что крайне важна скобочная оптимизация!

переписал алгоритм со скобочной оптимизацией - в итоге время прохождения алгоритма увеличилось в 5 раз! в моем случае оптимизации не произошло!!! давайте предметно говорить - как нужно скобки расставить чтобы был выигрыш в алгоритме?


(37)
И не понятно, зачем так всё усложнять?

не понял к чему? у меня продемонстрирован пример 3 - за счет алгоритма через "книги и страницы "- смотрите пример 3 - алгоритм ускорился в 60 раз !
41. Rustig 1408 11.01.22 09:52 Сейчас в теме
(40) а так в принципе я через алгоритм и тесты проверил и увидел, что работу со строками всегда можно оптимизировать за счет только алгоритмов (а не выбора объекта-типа-переменной) - алгоритм книг и страниц можно использовать для любого объекта - строка, текстовый документ, джейсон - далее посмотреть какой объект быстрее собирает итоговую строку - ну это уже не в моих интересах, поэтому дальше тестировать не буду с xml, памятью в потоке и т.д.
мне интересен был только алгоритмический подход... а не синтаксический....
34. Rustig 1408 10.01.22 22:43 Сейчас в теме
(21) вот результат для 100 000 строк и 50 строк на страницу- первые три примера:
539
17
12
Прикрепленные файлы:
35. Rustig 1408 10.01.22 22:46 Сейчас в теме
(21) 1) выходит, что задать массив с фиксированным кол-вом элементом - ускоряет выполнение кода на несколько секунд !!!
2) использование аналогии с книгой и страницами ускоряет алгоритм в 30-60 раз (в несколько раз) !!!!
36. Rustig 1408 10.01.22 22:52 Сейчас в теме
(21)
для замера другой функцией:
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	//первый пример
	Результат = "";
	Для Индекс = 1 По КоличествоИтераций Цикл
		Результат = Результат + "Это тестовая строка " + Строка(Индекс) + Символы.ПС;
	КонецЦикла;
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
	
	//второй пример
	Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок); 	
	Книга = Новый Массив; 	
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга.Добавить(Страница);  		
	КонецЦикла;
	
	//Результат = СтрСоединить(Книга, Символы.ПС);
	Результат = "";
	Для Индекс = 0 По КолСтраниц-1 Цикл
		Результат = Результат + Книга.Получить(Индекс);		
	КонецЦикла;	
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
	
	//третий пример
	Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Книга = Новый Массив(КолСтраниц);
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга.Добавить(Страница); 		
	КонецЦикла;
	
	//Результат = СтрСоединить(Книга, Символы.ПС);
	Результат = "";
	Для Индекс = 0 По КолСтраниц-1 Цикл
		Результат = Результат + Книга.Получить(Индекс);		
	КонецЦикла;
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
	
	//четвертый пример
	Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();

	Книга = "";
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга = Книга + Страница; 		
	КонецЦикла;
	
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);

Показать


результат для 30 000 строк и 60 строк на странице:
39 682
766
524
719
Прикрепленные файлы:
20. Pryanishnikov_Vladimir 10.01.22 08:41 Сейчас в теме
Для полной картины не хватает метода
ТекстовыйФайл = Новый ЗаписьТекста();
ТекстовыйФайл.ЗаписатьСтроку()
. В моей практике метод в разы быстрее текстового документа...
42. Darklight 27 11.01.22 12:13 Сейчас в теме
(20)"ЗаписьXML" (вариант 6) у меня более чем в 1.5 раза быстрее чем "ЗаписьТекста" (вариант 5 из статьи) - всё дело в том, что у варианта с "ЗаписьXML" меньше промежуточных объектов и операций - это очень старый классический вариант быстрой записи в строку - и он актуален и по сей день!
Но "ЗаписьJSON" ещё немного быстрее - при том же количестве кода (хотя при присединении более длинных строк происходит незначительное снижение производительности относительно "ЗаписьXML")!
Но быстрее всего - это варианты с "Массив+СтрСтоединить()" - рекомендуются для постоянного использования в современных конфигурациях и версиях платформы!
Эти варианты тяготеют к методике применения "StringBuilder" в C#
Причём вариант с предварительным выделением памяти под массив не даёт сколько-нибудь заметного прироста производительности (всё и без него работает очень быстро; начинаешь задумываться - может 1С оптимизировала работу с коллекцией "Массив" и ввела-таки экстенсивное выделением блоков памяти в резерв для следующих элементов?) - выполнение на 100K и 1М итераций (кол строк) дало даже обратный результат - выделение памяти заранее даже оказалось медленнее (а оба варианта с массивом были даже медленнее чем "ЗаписьJSON") - но это скорее всего артефакт чистоты эксперимента - всё-таки 1М cтрок заполняются достаточно долго! Да и в реальной практике такое количество - очень большая редкость! Тут скорее даже размер строки важнее - чем количество итераций.
Если провести анализ:
То инструкции алгоритма вида
ЗаписьТекста.ЗаписатьСтроку(Стр);
ЗаписьXML.ЗаписатьБезОбработки(Стр);
Массив.Добавить(Стр);
Массив[Индекс] = Стр;
Относительно друг друга занимают примерно одно и то же время (в % от выполнения всего алгоритма - причём примерно в 2 раза меньше времени - чем уходит на инструкции цикла "Для Индекс = 1 По КоличествоИтераций Цикл КонецЦикла" - что меня сильно удивило) - скорее всего почти все затраты времени - это передача значения переменной (скорее всего просто ссылки, без копирования всей области памяти - так как от размера Стр соотношение не меняется) и вызов метода обхекта с переключением контекста на его модуль реализации).
Финальное же формирование строки - методами
ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанныеИзПотокаВПамяти)
Закрыть()
СтрСоединить()
Почти не оказывают влияния (чем больше итераций - тем меньше их влияние, при сохранение итоговой длины строки; ну разве что СтрСоединить() чуть-чуть медленнее, чем Закрыть() записей XML/JSON и чуть-чуть быстрее чем ПолучитьСтрокуИзДвоичныхДанных() ).
Тем самым - основные затраты - это цикл - весь блок это более 99% всего времени во всех вариантах!
Тогда вывод такой - во всех указанных вариантах собственно обработка конкатенации строк идёт очень быстро - побочные затраты на цикл и вызовы методов объектов (в т.ч. скрытые - при присвоении индексированной ячейке массива значения) - куда более значительны и составляют почти всё время выполнения!
Работа с Массивом и функцией СтрСоединить - чуть быстрее, но она есть только с некоторого релиза 8.3 совместимости конфигурации и платформы. Работа с ЗаписьXML - является классической, старой, проверенной и почти такой же производительной!
Предварительное выделение памяти для Массива - как ни странно - играет даже обратную роль - может чуть снизить производительность (причём даже не за счёт затрат на конструкторе (хотя они тоже есть - но не значительны), а именно на присвоении значения ячейке массива по индексу (впрочем эти затраты тоже не значительны - но они находятся в цикле)).
Применение же классической конкатенации строк сильно проседает по производительности при числе строк свыше 1000. До 100 строк можно использовать и рядовую конкатенацию строк - друге способы не будут иметь значительного превосходства. А до 1000 строк - затраты времени по-прежнему будут фактически не велики (с учётом, что внутри цикла будет ещё какой-то продуктивный алгоритм) даже для рядовой конкатенации - но тут, конечно, ещё многое зависит от объёма строк - как быстро будет расти итоговая строка.
При числе итераций свыше 1000 всё зависит от затрат времени на продуктивном алгоритме внутри цикла - если он более 1 секунды на итерацию - тоже можно не заморачиваться на затраты времени на конкатенацию строк. В циклах свыше 10000 тыс строк уже настоятельно рекомендую выбрать любую оптимизацию конкатенации строк - даже если продуктивная часть будет ещё дольше - уж больно много времени будет занимать рядовая конкатенация строк.

Варианты с постраничным разбиением на массивы, предложенные в (33)-(38) - оказались не стабильны (всё зависит от размеров строк и их количества - разные размеры страниц бывает по-разному эффективны) - но все они, как минимум незначительно, проигрывают описанным выше вариантам - поэтому заворачиваться с постраничным разбиением смысла нет!

Некоторые мои замеры (мс):


Код:
Процедура Тест(КоличествоИтераций, Стр)
	//Стр2 = Стр + Символы.ПС;
	//т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	//Результат = "";
	//Для Индекс = 1 По КоличествоИтераций Цикл
	//    Результат = Результат + Стр2;
	//КонецЦикла;
	//Сообщить("Строка: "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));
		
	т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Результат = Новый ПотокВПамяти;
	ЗаписьТекста = Новый ЗаписьТекста(Результат);
	Для Индекс = 1 По КоличествоИтераций Цикл
	    ЗаписьТекста.ЗаписатьСтроку(Стр);
	КонецЦикла;
	ЗаписьТекста.Закрыть();   
	ДД = Результат.ЗакрытьИПолучитьДвоичныеДанные();
	Строка = ПолучитьСтрокуИзДвоичныхДанных(ДД);  
	Сообщить("ЗаписьТекста: "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));
	
	т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Результат = Новый ЗаписьXML;
	Результат.УстановитьСтроку();
	Для Индекс = 1 По КоличествоИтераций Цикл
	    Результат.ЗаписатьБезОбработки(Стр);
	КонецЦикла;
	Строка = Результат.Закрыть();
	Сообщить("ЗаписьXML: "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));
	
	т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Результат = Новый ЗаписьJSON;
	Результат.УстановитьСтроку();
	Для Индекс = 1 По КоличествоИтераций Цикл
	    Результат.ЗаписатьБезОбработки(Стр);
	КонецЦикла;
	Строка = Результат.Закрыть();
	Сообщить("ЗаписьJSON: "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));
	
	т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Результат = Новый Массив;
	Для Индекс = 1 По КоличествоИтераций Цикл
	    Результат.Добавить(Стр);
	КонецЦикла;
	Строка = СтрСоединить(Результат, Символы.ПС);	
	Сообщить("Массив: "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));
	
	т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	Результат = Новый Массив(КоличествоИтераций);
	Для Индекс = 0 По КоличествоИтераций-1 Цикл
	    Результат[Индекс] = Стр;
	КонецЦикла;
	Строка = СтрСоединить(Результат, Символы.ПС);	
	Сообщить("Массив(Кол): "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));
		
	//СтраницаКолСтрок = 40;
	//т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	//КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок);  
	//Книга = Новый Массив(КолСтраниц);
	//Для Индекс1 = 0 По КолСтраниц-1 Цикл
	//	
	//	Страница = "";
	//	Для Индекс2 = 1 По СтраницаКолСтрок Цикл             
	//		Страница = Страница + Стр2;             
	//	КонецЦикла;
	//	
	//	Книга.Добавить(Страница);         
	//КонецЦикла;
	//
	//Результат = "";
	//Для Индекс = 0 По КолСтраниц-1 Цикл
	//	Результат = Результат + Книга.Получить(Индекс);        
	//КонецЦикла;
	//c = ТекущаяУниверсальнаяДатаВМиллисекундах();
	//Сообщить("Массив страницы("+СтраницаКолСтрок+"): "+(c-т));  
	//
	//СтраницаКолСтрок = 60;
	//т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	//КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок);  
	//Книга = Новый Массив(КолСтраниц);
	//Для Индекс1 = 0 По КолСтраниц-1 Цикл
	//	
	//	Страница = "";
	//	Для Индекс2 = 1 По СтраницаКолСтрок Цикл             
	//		Страница = Страница + Стр2;             
	//	КонецЦикла;
	//	
	//	Книга.Добавить(Страница);         
	//КонецЦикла;
	//
	//Результат = "";
	//Для Индекс = 0 По КолСтраниц-1 Цикл
	//	Результат = Результат + Книга.Получить(Индекс);        
	//КонецЦикла;
	//c = ТекущаяУниверсальнаяДатаВМиллисекундах();
	//Сообщить("Массив страницы("+СтраницаКолСтрок+"): "+(c-т));  
	//
	//СтраницаКолСтрок = 100;
	//т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	//КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок);  
	//Книга = Новый Массив(КолСтраниц);
	//Для Индекс1 = 0 По КолСтраниц-1 Цикл
	//	
	//	Страница = "";
	//	Для Индекс2 = 1 По СтраницаКолСтрок Цикл             
	//		Страница = Страница + Стр2;             
	//	КонецЦикла;
	//	
	//	Книга.Добавить(Страница);         
	//КонецЦикла;
	//
	//Результат = "";
	//Для Индекс = 0 По КолСтраниц-1 Цикл
	//	Результат = Результат + Книга.Получить(Индекс);        
	//КонецЦикла;
	//c = ТекущаяУниверсальнаяДатаВМиллисекундах();
	//Сообщить("Массив страницы("+СтраницаКолСтрок+"): "+(c-т));
	//
	//
	//СтраницаКолСтрок = 1000;
	//т=ТекущаяУниверсальнаяДатаВМиллисекундах();
	//КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок);  
	//Книга = Новый Массив(КолСтраниц);
	//Для Индекс1 = 0 По КолСтраниц-1 Цикл
	//	
	//	Страница = "";
	//	Для Индекс2 = 1 По СтраницаКолСтрок Цикл             
	//		Страница = Страница + Стр2;             
	//	КонецЦикла;
	//	
	//	Книга.Добавить(Страница);         
	//КонецЦикла;
	//
	//Результат = "";
	//Для Индекс = 0 По КолСтраниц-1 Цикл
	//	Результат = Результат + Книга.Получить(Индекс);        
	//КонецЦикла;
	//c = ТекущаяУниверсальнаяДатаВМиллисекундах();
	//Сообщить("Массив страницы("+СтраницаКолСтрок+"): "+(c-т));

КонецПроцедуры
Показать
Прикрепленные файлы:
43. Diversus 2232 11.01.22 12:36 Сейчас в теме
(42) Почитайте комментарии, где я выше отписывался. Многое из того, что вы рассказали я уже в той или иной мере проговорил.
Про Capacity мое предположение почему выделение памяти заранее под Массив не ведет к тотальному увеличению скорости.
По поводу того, что ваши результаты не соответствуют моим, тоже есть. На разных машинах все может быть по разному. Общие тренды сохраняются плюс-минус, но позиции могут отличаться. Например, между компьютерами с процессорами Intel и AMD. Объемом ОЗУ и т.д. Все это в той или иной мере влияет на графики.
49. Darklight 27 11.01.22 13:31 Сейчас в теме
(43)
Про Capacity мое предположение почему выделение памяти заранее под Массив не ведет к тотальному увеличению скорости.

Насколько я знаю - ранее (в других алгоритмах работы с массивом) на Инфорстарт уже обсуждалось - что массивы проседают по производительности если их наполнять - без предварительного определения размера - а сейчас вижу обратную картину.

По поводу того, что ваши результаты не соответствуют моим, тоже есть. На разных машинах все может быть по разному.

Само собой - у всех по-разному - время зависит от аппаратной составляющей - а вот соотношения - по идеи от нюанса паттерна конкатенируемой строки (у меня везде фиксированная строка - разной длинны) и вероятно особенностей того или иного релиза платформы (интересно влияет ли режим совместимости - по идеи не должен, а вот версия платформы, под которой фактически всё запущено - должна влиять, как и режим упр или не упр приложения).
Суть основновнога вывода в том - что все способы оптимизации примерно одинаково производительны и общие накладные расходы в них берут верх - так что можно брать любой - и использовать, когда число строк в итерациях цикла будет явно больше 100 а то и больше 1000 (включая все циклы верхнего уровня - если они есть) - иначе можно не заморачиваться - оригинальная прямая конкатенация строка будет не особо проседать по производительности!

Забыл упомнить, что тестировал на релизе 8.3.19.1264 64Bit (на клиенте: Core i3 3.5Ghz 16Gb RAM; на сервере по сути ничего не меняется - но у меня тут виртуализация и невозможен чистый эксперимент серверного выполнения), но в 1С Бухгалтерия 3.0 в режиме совместимости конфигурации Версия 8.3.14 в управляемом режиме во внешней обработке). Надо бы ещё другие релизы попробовать - у меня есть 8.3.20.1674 (и конфа для него без установленной совместимости) - но что-то сегодня запускаться не стал (хотя до НГ 100% работал) - позже буду разбираться. Ну и меньшие релизы платформы надо глянуть (именно фактические, а не по режиму совместимости)!
44. Rustig 1408 11.01.22 12:52 Сейчас в теме
(42) ваши мысли, изыскания и алгоритмы интересны. спасибо, что нашли время написать так подробно.
45. Rustig 1408 11.01.22 13:01 Сейчас в теме
(42)
1Kx100

я не только не понял, что это за запись? что означает?
47. Darklight 27 11.01.22 13:10 Сейчас в теме
(45)1K=1000 итераций конкатенации порциями в 100 символов!
48. Rustig 1408 11.01.22 13:19 Сейчас в теме
(47) на одной строке не должно быть много символов - 100 символов это много - ограничимся 80 - 100 символов это уже не книга в моей концепции - придется учитывать длину строки, чтобы понять сколько строк на страницу влезет - а страниц в книге может быть много - как раз книга - это итоговый массив, состоящий из страниц....

Поэтому итоговую строку (итоговый результат) удобно получать через СтрСоединить(Книга, Символы.ПС)...

Пока что все на уровне интуиции...
50. Darklight 27 11.01.22 13:37 Сейчас в теме
(48)
на одной строке не должно быть много символов - 100 символов

Наверное мы о разных вещах - алгоритм не может влиять на то, какие строки ему поручают конкатенировать! Сами строки могут быть результатом работы других алгоритмов, и скажем, быть либо кусками запроса, либо кусками XML/JSON/HTML документов, или ещё чем....
И в этом закавыка для Вашего подхода - он очень чувствителен к размеру этих строк - меняется оптимум количества этих строк на одной странице от их размера!
51. Rustig 1408 11.01.22 14:10 Сейчас в теме
(50)чтобы оптимум найти, надо погрузиться в способ хранения данных в памяти, сколько байтов на каждую строковую переменную выделяет память, плюс понимать для какой операционной системы мы делаем замеры, плюс на каком ядре (с учётом его алгоритмов побитовых сложений)... Поэтому предлагаю на уровне интуиции договориться, что строка содержит не более 80 символов, на странице не более 60 строк, страниц может быть много... Мы же конкретную задачу решаем о строках - смотрите начало статьи.
52. Darklight 27 11.01.22 14:39 Сейчас в теме
(51)Алгоритм конкатенации не знает строки какой длины к нему поступать будут. И не может изменять их размер. И не может ни динамически ни статически оптимизироваться по этому критерию!
53. Rustig 1408 11.01.22 16:21 Сейчас в теме
(52) давайте не будем тестировать строки свыше 130 символов.
представим реальную задачу - у нас список из qr-кодов товаров легкой промышленности, около 30 000 марок.
какой алгоритм отработает быстрее?
ваш:
 т=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Результат = Новый Массив(КоличествоИтераций);
    Для Индекс = 0 По КоличествоИтераций-1 Цикл
        Результат[Индекс] = Стр;
    КонецЦикла;
    Строка = СтрСоединить(Результат, Символы.ПС);    
    Сообщить("Массив(Кол): "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));

и мой:
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок);
	Книга = Новый Массив(КолСтраниц);
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + Марка130символов + Символы.ПС; 			
		КонецЦикла;
		
		Книга.Добавить(Страница); 		
	КонецЦикла;
	
	Результат = СтрСоединить(Книга, Символы.ПС);
		
	Стоп = ТекущаяУниверсальнаяДатаВМиллисекундах();
	Сообщить(Стоп - Старт);
Показать


зададим 60 строк на страницу - возьму с неба - не знаю оптимума

сравниваем только эти два алгоритма работы со строками и массивами.

До использования джейсона или xml-записи я бы не додумался....Поэтому пока сравниваем алгоритмы работы со строками...
55. Darklight 27 11.01.22 17:52 Сейчас в теме
(53)Как уже сказал - алгоритм не может диктовать какие строки ему обрабатывать!
Но допустим. Я возьму даже строки короче - 10 символов и от 1000 до 1миллиона строк
Более того - я решил добавить ещё несколько тестов ПЛАЦЕБО - "условно" пустые функции, которые не производят конкатенацию вовсе
&НаКлиентеНаСервереБезКонтекста
Функция Пустая(Строка, Стр) экспорт
	Строка = Строка;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция Пустая2(Знач Строка, Знач Стр) экспорт
	Строка = Строка;
КонецФункции
Показать

Если код из них вовсе убрать - будет примерно в 2 раза быстрее (причём все варианты плацебо примерно одинаково по скорости) - но для тестов решил оставить так - тупо просто присвоение значения переменной себе же - по сути 100% пустышка - максимум что тут должно происходить - копирования ссылки на строку в стек, а потом обратно в ячейку памяти. А ну да - первая функция должна делать это дважды - так как аргументы передаются по в стек ссылке, и нужно их обратно отправить их значения в кучу!
По идеи - первая функция должна работать медленнее - так как ей нужно вернуть результат обратно в кучу!
Но суть не в этом, а в том - что тут нет конкатенации вовсе! Строка не растёт!
Но для эффекта - я передают не пустые строки - а уже заполненные предыдущим тестом - т.е. достаточно длинные!
Так же использую два контекста вызова - текущий (модуль текущей формы) и внешний (модуль второй формы или модуль объекта для сервера - получаются отдельно в начале)

#ЕСЛИ Клиент ТОГДА
	Контекст = ПолучитьФорму("ВнешняяОбработка.КонкатенацияСтрок.Форма.ФормаДоп");
	#ИНАЧЕ
	Контекст = Объект;
	#КОНЕЦЕСЛИ


Итого 4 плацебных вызова функций вид "Пустая_1(Строка, Стр)" (с "_" вызывают внешний контекст, без - текущий).

Ваш алгоритм тоже включил в тест - тестирую страницы 40, 60, 100, 1000 - для наглядности зависимости от размера страниц
Кстати - в этом алгоритме есть ошибка вот тут "КолСтраниц = Цел(КоличествоИтераций/СтраницаКолСтрок);" - при неровном делении - количество страниц будет меньше на 1 - а далее заполнение ориентируется на это количество - в итоге конкатенируется меньше строк. Да и сам алгоритм с книгой, на практике, будет сложнее - ведь ему придётся подстраивать своё заполнение под внешний поток строк (внешний цикл) - вложенные циклы тут буду крайне не желательны - так как встройка такого алгоритма в продуктивную среду может оказаться весьма затруднительной! от того - накладные расходы алгоритма возрастают ещё больше!

Вот результаты (в мс):


Тесты плацебо просто отжигают - конкатенации нет - а затраты времени на вызовы "условно" пустых функций колоссальные (при этом нагрузки на процессор почти нет)!
Что - в очередной раз показывает - что в данной задаче не важен метод решения (кроме прямой конкатенации) - всё упирается в общие накладные расходы платформенных инструкций цикла и внутренних вызовов - тогда имеет смысл выбирать тот алгоритм, который больше нравится и который удобнее вставить. Для 8.3 платформы я бы выбрал Массив + СтрСоединить() причём нет смысла даже массив заранее создавать заданного размера!

На у оптимальное универсальное число страниц видимо действительно 60 :-D
Но страничный метод всё-равно медленнее или как минимум не быстрее просто единого Массива - так что ещё раз подчёркиваю смысла заморачиваться со страничным методом нет! Это усложнение на пустом месте!

Прилагается скриншот распределения времени по плацебо-функциям в сравнении с распределением времени на алгоритм конкатенации через ЗаписьJSON.ЗаписатьБезОбработки(Стр)
Для 1000 и 100 000 строк по 10 символов
В % затраты времени только на вызов функции (без затрат на её пустую работу)

Ещё добавлю - что при большом количестве строк вызов от вызова затраты времени могут заметно гулять и на разные алгоритмы могут быть на разных местах по эффективности. Как уже сказал ранее - особенно это касается страничных вариантов - они самые нестабильные!
Прикрепленные файлы:
56. Rustig 1408 11.01.22 17:58 Сейчас в теме
(55) все понятно. согласен. спасибо.
57. Perfolenta 198 12.01.22 03:12 Сейчас в теме
(55) просто к сведению, в экспериментах с Net Framework я выяснил, что там есть граничная длина строк, после которой скорость конкатенации резко падает, но после излома график всё равно растет линейно... падение скорости конкатенации за граничной точкой составляет от 3 до 5 раз и точнее измерить не удается, т.к. видимо влияют другие процессы работающие в этот момент на компе...
Эта граница для 64-битных процессов грубо находилась в районе 100 килобайт, а для 32-битных процессов 50 килобайт... если общая длина суммируемых строк короче, то скорость конкатенации значительно выше...
В 1С такой границы обнаружить не удается и в целом в 1С конкатенация строк превышающих границу отрабатывает примерно в те же 3-5 раз быстрее, чем в Net... правда, в Net есть StringBuilder, который просто вне конкуренции и работает в 100-200 раз быстрее, чем простая конкатенация...
58. Darklight 27 12.01.22 10:03 Сейчас в теме
(57)
после которой скорость конкатенации резко падает

При каком методе конкатенации? Прямым сложением?
Строки в .NET константные ссылки на область в памяти. Прямое сложение - это создание новой строки, путём копирования в новую область памяти складываемых частей. Если я правильно понимаю механизм CLR - то если такая итоговая строка уже есть в памяти - то копирования не происходит - и просто возвращается ссылка на новую строку (но это надо проверить, так как не совсем ясно как определяется наличие такой строки в памяти).
Чем больше строка - тем больше нужна область в памяти для хранения символов. А память обычно фрагментирована - то есть в ней попросту может не быть свободной области нужного размера - тогда запускается сборщик мусора по полному циклу сборки и реструктуризации памяти данного домена приложения (для .NET Framework, что там с .NET CORE и .NET 5 я не в курсах вовсе - там ведь нет домена приложения). Соответственно при следующей конкатенации - скорее всего придётся искать новую область ещё большего объёма (но последовательная сборка мусора будет уже идти куда быстрее и более предсказуемо - память то уже в целом упорядочена) - о того и падение скорости и сохранение линейного графика времени выполнения. Но 100 кб - это как-то уж очень мало - не такая уж большая область. Кстати - как мерились эти 100кб (по сути это где-то 50K символов в UTF16 - ведь так строки хранятся в .NET; + кроха памяти на пару внутренних полей объекта System.String)?

В 1С такой границы обнаружить не удается и в целом в 1С конкатенация строк превышающих границу отрабатывает примерно в те же 3-5 раз быстрее, чем в Net

Вот это реально удивило. Этож насколько падает скорость в .NET - что её 1С так лихо начинает обходить там, где 1С сама уже безбожно тормозит! Это на .NET Framework 4.7? Может другие фреймворки попробовать (не только 4 версию но и 5 и 6, можно ещё и .NET CORE 3.1 попробовать - хоть он и устарел, но там могут быть свои особенности, до слияния в 5 версии с .NET Framework 4).
То что в 1С нет такой просадки - скорее большая удача или попросту иной планировщик памяти в платформе 1С: Предприятие 8 - что не приходится каждый раз под новую строку решать проблемы её размещения!

правда, в Net есть StringBuilder, который просто вне конкуренции и работает в 100-200 раз быстрее, чем простая конкатенация

Всё-таки работу StringBuilder имеет смысл сравнивать с работой СтрСоединить() по массиву в 1С - принцип их работы очень схож (ну разве что у StringBuilder чуть помощнее API форматирования и некоторые общие сервисные функции).
Проблем с резким замедлением у StringBuilder нет - так как изначально строки хранятся в отдельных ячейках ссылок на разные области памяти, а когда доходит до сборки итоговой строки - он сразу знает какого объёма нужна область памяти - сразу её выделяет (если надо - один раз запускается сборщик мусора) и в один цикл копирует туда память из исходных областей. То же делает и СтрСоединить() в 1С.

Вот, если я бы проектировал управляемый ЯП - я бы при конкатенации строк не копировал бы их физически - а конкатенировал лишь список ссылок на фрагменты (в т.ч. на части фрагментов). Вот когда эти фрагменты требовалось бы изменить - это уже другое дело (но опять же - если изменяемый фрагмент входит только в одну строку - то его можно смело менять без копирования; или выделить в отельные фрагменты неизменяемую часть и изменённую - это уже решается в runtime - по фактическому анализу ситуации) - но для строк обычно это плохой дизайн (нужно использовать другие объекты, в т.ч. временно - для проведения массовых изменений) - строки обычно константы или списки констант. По сути - у меня бы строки были продвинутым StringBuilder.
Даже при выделении подстроки - это просто формирование новых границ фрагмента на ту же область памяти - поэтому эффективность была бы не только при конкатенации, но и при подстрочном разбиении строки.
Что-то типа Span коллекций в .NET (и, возможно, но вряд ли, БуферДвоичныхДанных в 1С 8.3)
59. Perfolenta 198 12.01.22 13:12 Сейчас в теме
(58)
При каком методе конкатенации? Прямым сложением?

да, это был эксперимент со String.Concate
если такая итоговая строка уже есть в памяти - то копирования не происходит - и просто возвращается ссылка на новую строку

Это касается только интернированных строк....
как мерились эти 100кб (по сути это где-то 50K символов

верно, я просто умножил на 2 длину строки после превышения которой скорость резко падала
Это не на .NET Framework 4.7?

Это на .NET Framework 4.8.. на других не пробовал... на других конечно могут быть свои особенности..
То что в 1С нет такой просадки - скорее большая удача или попросту иной планировщик памяти в платформе 1С: Предприятие 8

ну да, выходит, что в 1С хороший алгоритм используется... раньше 1С 8.2 была внутри на COM основана и там использовались строки BSTR, а сейчас не знаю...
Всё-таки работу StringBuilder имеет смысл сравнивать с работой СтрСоединить

только что сравнил... StringBuilder обгоняет 1С Массив+СтрСоединить примерно в 10 раз...
скорее всего из-за медленной работы самого цикла заполняющего массив...
Вот, если я бы проектировал управляемый ЯП - я бы при конкатенации строк не копировал бы их физически - а конкатенировал лишь список ссылок на фрагменты (в т.ч. на части фрагментов).

да, идея отличная, особенно с учетом принципа неизменности строк... но почему-то разработчики Net так не сделали... можно наверное это сделать и в своём компиляторе, но это уже сложнее, т.к. придется делать особую аналитику, где обычные строки, а где модерновые, и когда надо одни превращать в другие, ведь язык IL знает только про обычные... у меня в Перфоленте пока только есть анализ обычной последовательной конкатенации и простейшие оптимизации основанные на количестве конкатенируемых строк..
60. Darklight 27 13.01.22 13:29 Сейчас в теме
(59)
Это касается только интернированных строк....

Ооо... не знал - что для этого не литеральные строки явно надо интернировать - жаль... явно этого никто делать почти никогда не будет! А без этого теряется весь смысл их компактезации в памяти! И сохранение памяти, скажем, если я буду читать из файла потока много одинаковых строк (в т.ч. в разнобой)! А потом ещё и сравнивать их на равенство (обычное сравнение то пройдёт - но будет неоптимально долгим для длинных строк) - то эффективность будет куда ниже.
Кстати, как я понял - явное интернирование не убирает из памяти исходный дубль строки - и он будет её занимать (не имея ссылок на него) до очередной чистки мусора - что тоже не очень хорошо!

да, это был эксперимент со String.Concate

Не удержался - провёл свой эксперимент на C# и .NET Core 3.1
Хотел отследить моменты выполнения сборки мусора - но адаптированный пример с MSDN у меня не сработал. Но другим путём я, всё-таки, частично отследил моменты сборки мусора.
При посимвольной конкатенации 1М строки примерно происходит более 200K сборок мусора (после примерно 500 сборок новые конкатенированные строки создаются уже в куче поколения 2 - минуя 1 - видимо из-за больших размеров - как раз где-то около 50K символов). Переход на поколение 2 - это первое серьёзное замедление - прибавка одного символа занимает порой 27K тиков. У меня это произошло уже через 420 миллисекунд от начала теста.
Но замедления начинаются ещё до перехода на поколение 2. Первые просадка у меня возникают около 25K символов и потом было ещё несколько - но это разовые пики - скорее всего просто огрехи не чистого эксперимента, ну или при выделении памяти в этом момент были разовые сложности поиска свободного блока нужной длинны - хотя 50KB - это смехотворный блок.
В первом поколение среднее время добавления одного символа около 40тиков - но надо заметить - что оно растёт с ростом строки - оно и понятно - длинная строк - требуется больше время на её копирование при конкатенации.
Но и тут случаются пиковые периодические небольшие, но явно выраженные просадки до 3K до 10K тиков. Скорее всего - всё это связано с задержками выделения памяти. При этом, бывает и обратное - на создание новой конкатенированной строки длиной около 1.5K символов может потребоваться 1-3 тика - это ОООЧЕНЬ мало!
Мне кажется - CLR в .NET делает какую-то оптимизацию операции конкатенации строк - не всегда копируя исходную строку - а именно добавляя символ к концу массива байтов - причём заранее выделяя памяти побольше для таких операций - просадки - это как раз выделения новых блоков памяти!

С переходом на поколение 2 ситуация в начале немного меняется - вырастает среднее время добавления символа - где-то до 400тиков - но по-прежнему есть большой разброс. И пиков становится куда больше (в среднем ещё не большие - около 3К-8К) - на графике (прилагается) явно виден забор (показаны большие приросты за которыми сразу же следуют большие падения). Но в целом среднее время добавления тоже начинает расти. Но главное - резко начинает расти количество сборок мусора во втором поколении (где их как раз должно быть мало по архитектуре построения второго поколения управляемо кучи). И пики начинают совпадать с этими моментами сборки мусора.

После 200K символов среднее время вырастает уже до 700тиков. А пики в среднем уже 5К-10К тиков.

Следующий прирост уже около 500K символов. В среднем около 4K тиков требуется на добавление символа. И пиковые задержки становятся более значимыми - около 15K-30K тиков - видом уже и в зоне 2-го поколения кучи начинаются проблемы с выделением памяти под блоки такого большого размера. На отметке 600K с небольшим символов был большой разовый выброс 100K тиков на добавление символа.

Но самое интересное случилось под конец - с отметки 780K символов начались большие выбросы времени конкатенации очередного символа к строке от 123K до 220K тиков. А среднее добавление символа стало около 8K.
Прохождение этого этапа заняло более 60% времени всего заполнения (и около 40% всех сборок мусора)
На лицо проблемы сборки мусора - видимо часто приходилось активно расширять зону памяти поколения 2 - и перемещать туда исходную зону.

Ещё один интересный график - это график корреляции среднего времени добавления символа к удельному приросту времени добавления символа в значимых точках такого прироста, в распределении по шкале количества сборок мусора (удельный прирост - это отношение пиковой единицы прироста к количеству сборок мусора в периоде, где был этот пиковый прирост - т.е. Средний прирост за одну сборку мусора - ведь не каждая сборка мусора образовывала увеличивающийся пик)
На этом графике, на мой взгляд, достаточно чётко видна зависимость пиков среднего времени добавления символа, от пикового удельного прироста времени при очистке мусора в поколении 2. По шкале капительного количества очисток мусора. Линейный рост среднего тут неизбежен из-за удлинения строки.

С 1С такой тест не сравнить - посимвольно 1С Предприятие 8 бы конкатенировало бы строку длиной в 1M более месяца! Но у меня на .NET весь тест занял около 4.5 минут (чистого времени - строго по замерам только операции конкатенации, с высокой точность). Поэтому я не могу сказать - что конкатенация в .NET на длинных строках проседает сильнее, чем на 1C. Ну, конечно, можно попробовать большими порциями конкатенировать строку - и тогда уже сравнить с 1С
Прикрепленные файлы:
61. Perfolenta 198 13.01.22 19:28 Сейчас в теме
(60) спасибо, для меня это интересная информация...

С 1С такой тест не сравнить - посимвольно 1С Предприятие 8 бы конкатенировало бы строку длиной в 1M более месяца!

не знаю, может я не правильно Вас понял про 1М, но вот такой код 1С на моём ноутбуке выполнила за 291 секунду, т.е. чуть больше 4-х минут...
Строка = ""; 
т=ТекущаяУниверсальнаяДатаВМиллисекундах();
Для Индекс = 1 По 1000000 Цикл
    Строка = Строка+"Ф";
КонецЦикла;
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах()-т);

в то же время Net 4.8 потратил 345 секунд, т.е. почти 6 минут...
Надо учесть, что пустой цикл в 1М итераций на 1С выполняется в среднем 500 мс, а на Net от 0 мс до 7 мс (раз на раз не приходится, да и точность ТекущаяУниверсальнаяДатаВМиллисекундах меньше 15 мс не гарантирована)...
54. Rustig 1408 11.01.22 16:35 Сейчас в теме
ваш алгоритм отрабатывает быстрее - стабильно быстрее ровно на 450 миллисекунды - для разных количеств марок и кол-ств строк на странице.
марку нашел в инете на ИС, использовал ее 129 символов: Стр = "010290000024799421tw:C:VWHj*_FeØ918029Ø92mSgFXJhvOUzoXp9S1TpKlUqt5526jYj+haVvxTfSznl0cE6JBXTxBBls+d­EUFD9OBeQ6w5PH2w/j2G5FPQprSQ==";


ну что ж - и правда мудрить с дополнительными блоками в виде страниц книг - оказалось неоправданно
46. Rustig 1408 11.01.22 13:09 Сейчас в теме
(42)
т=ТекущаяУниверсальнаяДатаВМиллисекундах();
Результат = Новый Массив(КоличествоИтераций);
Для Индекс = 0 По КоличествоИтераций-1 Цикл
Результат[Индекс] = Стр;
КонецЦикла;
Строка = СтрСоединить(Результат, Символы.ПС);
Сообщить("Массив(Кол): "+(ТекущаяУниверсальнаяДатаВМиллисекундах()-т));


сравните только два алгоритма: вот этот ваш в цитате
и второй мой :
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
	
	Книга = Новый Массив(КолСтраниц);
	Для Индекс1 = 0 По КолСтраниц-1 Цикл
		
		Страница = "";
		Для Индекс2 = 1 По СтраницаКолСтрок Цикл 			
			Страница = Страница + "Это тестовая строка " + Строка(Индекс1*СтраницаКолСтрок + Индекс2) + Символы.ПС; 			
		КонецЦикла;
		
		Книга.Добавить(Страница); 		
	КонецЦикла;
	
	Результат = СтрСоединить(Книга, Символы.ПС);
Показать


для данных - любая книга всегда содержит такое кол-во строк на странице, чтобы можно было комфортно держать ее в руке и читать - то есть 40-50-60 строк на страницу... Не нужно 100 строк на страницу - в этом нет ничего научного, и все требует доказательств.... и все же книга как Война и мир содержит много страниц и мало строк на каждой странице - это нормально - это вписывается в мою концепцию....

Я бы конечно не придумал использовать для подобных задач ни xml, ни джейсон.... поскольку не вижу как внутри устроены эти объекты на уровне ООП (что инкапсулировано в их методах и свойствах)... Но я бы заморочился только на строках и оптимизации работы со строками - отсюда мой пристальный интерес к алгоритму обхода строк.... не более и не менее....

а так спасибо за ликбез вам и автору статьи - есть над чем подумать
22. Darklight 27 10.01.22 10:00 Сейчас в теме
Для полноты эксперимента можно было бы привести тесты (отдельный график) и для ОЧЕНЬ большого количества конкатенаций: то есть явно больше 10тыс строк - скажем от от 100 тыс до 1миллиарда (главное чтобы памяти хватило и не начался свопинг - но тут уже явно нужен сервер с большим количеством ОЗУ, чтобы исключить свопинг).
Пусть такой тест можно считать искусственным - но он может показать более тонкие нюансы в производительности некоторых способов, идущих на меньших объёмах почти на равных (при этом из такого теста можно сразу выкинуть явных аутсайдеров - чтобы оптимизировать масштаб графика - кстати не плохо было бы подписать значения цифр на осях координат).

И да - как было сказано выше - не хватает и графика замера по расходу памяти (как и указание тех характеристик хардварной платформы, на которой производилось тестирование); так же, для полноты картины, как мне кажется, не хватает тестов на разных версиях платформах 1С Предприятие 8. В т.ч. как под Windows так и под Linux.

Неплохо было бы и сравнить графики нагрузки на процессор!

Ну и ещё можно было бы продемонстрировать корреляцию разных методов в зависимости от длины конкатенируемых строк - скажем размерами порций 100, 1К, 10К, 100K, 1000K (естественно не на 1Млрд строк, а не более чем 10K строк).

P.S.
Считаю, что можно было бы сделать и отдельный график для малого количества конкатенируемых строк (до 1000 включительно) - тоже выкинув явных аутсайдеров, чтобы оптимизировать масштаб графика. Где наглядно показать какие методы эффективнее на малых конкатенациях, пусть и эта эффективность в таких операциях и окажется незначительной.
Конечной, такие малые тесты хорошо бы зациклить хотя бы на 1000 (а лучше на 10K-100K) повторов - для достижения статистической точности на малых временных отрезках измерений!
Ведь чаще всего их как раз не так уж и много конкатенируется - зато наглядно будет видно - стоит ли заморачиваться с оптимизацией - и если заморачиваться - то какой способ лучше всего выбрать для универсального применения!
25. Diversus 2232 10.01.22 11:14 Сейчас в теме
(22) Обработка прилагается к статье. Если хотите протестировать работу в разных средах или на разном количестве итераций, то можно скачать и попробовать самостоятельно.
23. Азбука Морзе 101 10.01.22 11:11 Сейчас в теме
Совершенно не отражены приемы работы с СКД. В частности агрегатная функция СоединитьСтроки().
24. Diversus 2232 10.01.22 11:13 Сейчас в теме
(23) В моем примере совсем о другом речь. Речь о конкатенации обычных строк, а не работа с СКД.
26. Азбука Морзе 101 10.01.22 11:17 Сейчас в теме
(24) Массив обычных строк можно передать в макет компоновки, обработать и вывести в итоговую строку процессором вывода. Думаю результат удивит многих.
27. Diversus 2232 10.01.22 11:21 Сейчас в теме
(26) Способ с массивом уже есть. Львиная доля всего времени пойдет на формирование этого массива.
И вряд ли передача данных в макет компановки будет работать быстрее, чем СтрСоединить... Но это надо бы протестировать.
Для чистоты эксперимента, если будет время, попробую проверить позже.
28. Darklight 27 10.01.22 12:07 Сейчас в теме
(27)Если память под массив выделена заранее (что не было протестировано) - то львиная доля времени - это уже работа функции СтрСоединить () - ну или вызов СКД - другое дело - что этот вызов скорее всего будет тяжелее чем вызов СтрСоединить () - но попробовать можно. Конечно сравнивать надо в одном контексте - Серверном - так как все вызовы СКД выполняются на Сервере
30. Diversus 2232 10.01.22 13:15 Сейчас в теме
(28) Да - это будет интересно.
31. awk 733 10.01.22 13:46 Сейчас в теме
Как производился замер?
32. Diversus 2232 10.01.22 13:49 Сейчас в теме
(31)
ВремяНачальное = ТекущаяУниверсальнаяДатаВМиллисекундах();
...
// То, что замеряем
...
ЗатраченоВМиллисекундах = ТекущаяУниверсальнаяДатаВМиллисекундах() - ВремяНачальное;
39. John_d 3735 11.01.22 09:42 Сейчас в теме
В итоге, чтобы не сильно заморачиваться надо использовать Массив и функцию, которую 1с специально сделала для этих целей СтрСоединить.
Darklight; +1 Ответить
Оставьте свое сообщение

См. также

FormCodeGenerator Программная доработка форм. Часть 2 (Режим работы "Режим сравнения форм") на примере ERP 2.5 Промо

Адаптация типовых решений Прочие инструменты разработчика Практика программирования v8 1cv8.cf Абонемент ($m)

Данная публикация является продолжением описания функционирования обработки "FormCodeGenerator " в режиме сравнения форм и генерирования кода на основании сравнения. Подходит для перевода уже доработанных форм с интерактивной доработки на программную. Данный режим работы обработки снизит издержки при дальнейших обновлениях конфигураций.

5 стартмани

21.12.2020    11502    27    huxuxuya    11    

"Привет, 1С": простейший голосовой ассистент для 1С. UPD: с исходниками

Практика программирования v8 Абонемент ($m)

Программулька, которая при наличии микрофона превращает вашу 1С в "умную колонку": постоянно слушает микрофон и при произнесении активационной фразы позволяет выполнять команды, которые вы в 1С определите. Например, ответить "сколько заказов сегодня" или "сколько денег в кассе". А также может принимать запросы от 1С для того, чтобы оповестить голосом (text-to-speech) или задать вопрос и отправить ответ в 1С.

1 стартмани

10.12.2020    8685    60    informa1555    77    

Интерактивная справка по объектам 1С (подключаемое расширение)

Работа с интерфейсом Практика программирования v8 ERP2 Абонемент ($m)

База знаний, подключаемая к объектам основной базы. Пополняется интерактивно, формируется в виде статей прямо в 1С (текст, картинки, таблицы, ссылки). Есть возможность прикрепления файлов, привязки к объектам 1С, возможности рейтинга и комментирования пользователями.

5 стартмани

29.09.2020    17347    95    sapervodichka    52    

HTTP сервисы по OpenAPI спецификациям

WEB Практика программирования v8 1cv8.cf Абонемент ($m)

Начинаем путь разработки HTTP сервисов с создания спецификаций OpenAPI. Автодокументация сервисов формата Swagger UI без зависимостей. Настройка сервисов в режиме предприятия.

1 стартмани

29.06.2020    17321    18    shmalevoz    22    

Вам нравятся запросы в 1С? Промо

Практика программирования v8 v8::Запросы 1cv8.cf Абонемент ($m)

Речь не только о том, что простейший запрос с "легальным" оформлением растянется на пол-экрана, речь еще обо всем, что нужно написать "в нагрузку" к тексту запроса. Все эти "Новый Запрос", "УстановитьПараметр" и последующие пляски с обработкой результата... Пора с этим заканчивать!

1 стартмани

03.07.2019    29682    7    m-rv    91    

Алгоритмы поиска пути в графе. Часть 2

Практика программирования v8 1cv8.cf Абонемент ($m)

Новые возможности, ранее реализованных алгоритмов поиска пути в графе на платформе 1С 8.3.

1 стартмани

13.08.2019    9202    9    RonX01    10    

Удобный выбор из таблицы/дерева в УФ

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Выбор из таблицы значений или дерева значений в выпадающем списке рядом с полем ввода - УФ, быстро и просто!

1 стартмани

12.08.2019    19376    8    Yashazz    18    

Рисуем и распознаем нарисованное при помощи нейросети

Работа с интерфейсом Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Используем нейронную сеть для распознавания нарисованных объектов.

1 стартмани

03.10.2018    19357    47    DO_WHILE_LOOP    28    

ВСТАВИТЬ В Справочник.Номенклатура (Код, Наименование) ЗНАЧЕНИЯ ("001", "Новый товар") Промо

Практика программирования v8 v8::Запросы 1cv8.cf Абонемент ($m)

Вас не обманывают ваши глаза, это запрос на изменение данных! И это работает без прямого доступа к БД, регистрации и смс.

1 стартмани

01.06.2018    38625    97    m-rv    58    

Работа с публикациями "Инфостарт"

Инфостарт WEB Практика программирования v8 УУ Абонемент ($m)

Работа с рублевыми публикациями на сайте "Инфостарт": ведение клиентов, заказов, обновление файлов публикации, рассылка обновлений.

1 стартмани

13.09.2018    30439    15    RocKeR_13    16    

Продвинутое рисование в табличном документе (стрелок и не только)

Работа с интерфейсом Практика программирования v8 Абонемент ($m)

Вспоминаем геометрию и основы компьютерной графики. Матрицы и аффинные преобразования на плоскости.

1 стартмани

24.07.2018    21953    21    WalterMort    31    

Полезный код для программистов 1С (часть 2). Помощник заполнения.

Практика программирования v8 Абонемент ($m)

Продолжение статьи с некоторыми инструментами, которые мы используем в своей работе. На этот раз дошли руки до механизма реализации заполнения табличных частей, на основании остатков и других ранее введенных данных.

1 стартмани

20.07.2018    17704    15    vandalsvq    15    

Заполняем по шаблону (по умолчанию) Промо

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Простой в подключении, универсальный и достаточно удобный механизм заполнения реквизитов произвольных документов/справочников значениями по умолчанию. Реализован в расширении, но может быть и непосредственно включен практически в любую конфигурацию на управляемых формах простым копированием одной формы и двух команд. Весь код в статье.

1 стартмани

08.02.2018    36568    20    mvxyz    17    

Работа с данными выбора

Работа с интерфейсом Практика программирования v8 Россия Абонемент ($m)

В управляемом интерфейсе заложена мощная возможность описывать связи реквизитов формы через параметры. Установка параметров связей позволяет ограничить выбор данных так, чтобы целостность данных была обеспечена на этапе ввода. Однако без дополнительного программирования задать можно только самые простые связи. Такие условия связи, как зависимость от реквизита через точку или зависимость через дополнительное отношение, заданное в регистре сведений - уже задать без программирования не получится.

1 стартмани

17.07.2018    72535    25    kalyaka    17    

Полезные примеры составления схемы компоновки данных #2

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Еще один набор примеров как решить частные задачи в СКД

1 стартмани

22.05.2018    43067    11    SITR-utyos    13    

Печатная форма, сделанная как расширение конфигурации для БП 3.0. Новые возможности БСП

Практика программирования v8 БП3.0 Абонемент ($m)

Печатные формы на внешних обработках скоро канут в лету. На смену им приходят ПФ, реализованные в виде расширений конфигурации. Не нашел на сайте примеров таких расширений. Привожу пример подобного расширения для БП 3.0.

1 стартмани

06.12.2017    34959    60    kwazi    6    

Нечеткий поиск одним запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

28.12.2015    36361    76    vasvl123    9    

Паузы при исполнении кода (Sleep для 1С)

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Решил проверить все найденные варианты паузы для 1С. В результате получилась обработка для тестирования и небольшая статья с итогом.

1 стартмани

28.11.2017    73510    19    swimdog    55    

Вставка снимка экрана (screenshot) в форматированный документ

Практика программирования v8 Россия Абонемент ($m)

Пример работы с буфером обмена и программной вставки скриншота в форматированный документ.

1 стартмани

30.08.2017    28765    50    Boneman    14    

Умный дом на 1С + ардуино

Практика программирования v8 Абонемент ($m)

Конфигурация для автоматизации быта программиста 1C и не только. В данной статье будет рассказано, как можно использовать 1С для задач, не входящих в стандартные рамки этой платформы. Например, управление домом. В качестве периферии для подключения будет использован микроконтроллер (МК) Ардуино, но на нём не будет никакой логической нагрузки, весь процесс будет проходить на сервере 1С. Работа с пинами ввода/вывода происходит напрямую из 1С.

1 стартмани

07.08.2017    29602    21    sasha777666    64    

1С: Предприятие + корпоративный чат, как наладить оперативные уведомления за 10 минут Промо

Практика программирования v8 Абонемент ($m)

Как сделать автоматические уведомления о разных событиях из 1С в корпоративный чат MyChat для сотрудников компании

1 стартмани

14.08.2016    56765    36    Demanoidos    60    

Расширения конфигураций 1С: учимся перехватывать методы

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

В этой статье я на примерах разберу некоторые механизмы расширений конфигураций 1С. А именно «перехваты» методов модуля объекта и «перехваты» событий формы и элементов формы. Данная статья написана с учебными целями, чтобы показать, как при помощи расширений конфигурации можно делать такие доработки, ради которых раньше приходилось снимать конфигурацию с поддержки.

1 стартмани

30.05.2017    174509    13    signum2009    49    

Рисуем в 1С

Практика программирования v8 1cv8.cf Абонемент ($m)

Вдруг захотелось порисовать в paint, а его использование заблокировано корпоративными политиками. Бывало такое? Тогда прошу под кат...

1 стартмани

11.05.2017    23781    74    pallid    35    

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

Практика программирования v8 Россия Абонемент ($m)

Какие события и в какой последовательности вызываются платформой 1С? Куда лучше поместить свой программный код, чтобы добиться нужного поведения программы? Предлагаю разработку «Изучение событий» которая облегчит поиск ответов на такие вопросы.

2 стартмани

12.03.2017    28067    44    rusmil    21    

Быстрое определение интервалов в запросе Промо

Практика программирования v8 Абонемент ($m)

В статье описывается новый метод определения интервалов между данными различных записей в запросе. В отличие от общеизвестного метода, время работы предлагаемого метода зависит от объема данных ЛИНЕЙНО. Это обеспечивает ему значительный выигрыш по быстродействию на больших объемах данных. В качестве иллюстрации возможностей метода приведен отчет, показывающий гистограмму распределения времени между продажами.

1 стартмани

01.10.2015    63212    35    ildarovich    41    

Распознавание текста с помощью нейросетей Google Cloud Vision и 1С

Практика программирования v8 1cv8.cf Абонемент ($m)

Возможности Google Cloud Vision в распознавании текста.

1 стартмани

08.02.2017    40854    153    kiv1c    19    

Графическая схема. Управление при помощи XDTO.

Практика программирования v8 Абонемент ($m)

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

2 стартмани

16.01.2017    31393    134    Alxby    25    

Простой редактор плана помещения JavaScript

Работа с интерфейсом Практика программирования v8 1cv8.cf Абонемент ($m)

На ресурсе сейчас очень много решений, которые позволяют редактировать карты, используя географические схемы. Так же много решений, которые позволяют редактировать объекты онлайн веб-карт. Мне же нужно было простое решение, для того чтобы расставить квадратные объекты на плане, показать их пользователю. Ну и распечатать, опять же. Я решил написать простенький редактор на JavaScript с использованием библиотеки Raphael.

1 стартмани

23.11.2016    28701    108    igel9780    23    

Хранение файлов в томах на диске (для УПП 1.3) Промо

Практика программирования v8 УПП1 Абонемент ($m)

Доработка типовой УПП 1.3 в плане хранения присоединенных файлов вне базы данных

2 стартмани

05.06.2016    70594    14    wowik    32    

Работа с двоичными данными на примере чтения файлов изображений. Новые возможности 8.3.9

WEB Практика программирования v8 1cv8.cf Россия Абонемент ($m)

В статье приводятся новые функции по работе с двоичными данными, появившимися в версии платформы 8.3.9 , на примере анализа формата и размера изображений. А также пример отправки изображения через API ВКонтакте с помощью новых объектов (без использования ОбъединитьФайлы())

1 стартмани

14.11.2016    37366    19    Anton64    24    

Загрузка файлов на сервер с прогрессом и докачкой

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Пример использования новых возможностей платформы 8.3.9 по низкоуровневой работе с двоичными данными для инкрементальной передачи файлов на сервер.

1 стартмани

04.10.2016    18388    58    mrstomak    21    

HTTP-сервис: отчеты [Расширение]

Работа с интерфейсом Практика программирования v8 1cv8.cf Абонемент ($m)

Это HTTP-сервис, который возвращает почти любой отчет в HTML, XLSX или в JSON. Сохраните вариант отчета, получите на него ссылку и можно получить данные без захода в 1С. Работает в конфигурациях на основе БСП 2.3.3+, для отчетов на СКД и в 1С 8.3.8+

2 стартмани

30.08.2016    35802    160    Stepa86    16    

Порождающий запрос Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Иногда в запросе необходимо получить искусственную таблицу заданного размера, не связанную с данными информационной базы. Эта получаемая «из воздуха» таблица может быть заполнена, например, числами натурального ряда или функционально связанными с ними значениями. Такая таблица может пригодится как временная таблица в запросе для соединения с реальными таблицами. Другой вариант – быстрое получение таблиц значений заданного размера, списков, массивов и прочее. В последних версиях MS-SQL есть возможности непроцедурной генерации таблиц посредством специального «итеративного» описания. Ну а для 1С пригодится следующее решение:

1 стартмани

15.09.2011    72279    153    ildarovich    89    

Недокументированное использование стандартных форм Upd.

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

Вам не хватает возможностей в платформе 1С или у Вас нет времени на углубленное изучение платформы 1С? Рассмотрены возможности использования стандартных форм, вызываемых из платформы.

1 стартмани

26.07.2016    35666    109    ZhokhovM    69    

Выполнение JavaScript кода из 1С в объекте Поле HTML Документа (HTML 5) и вызов события в 1С ПриНажатии

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Пример выполнения JS кода из 1С в Поле HTML Документа под управляемыми формами, с удобным получением результата в 1С(С помощью вызова привязанного события ПриНажатии к элементу ПолеHTMLДокумента)

1 стартмани

22.03.2016    99435    173    igo1    62    

Количество дней недели (понедельников/вторников/...) в заданном диапазоне одним запросом

Практика программирования v8 Абонемент ($m)

При реализации периодического авто-заполнения маршрутных листов по графику (недельному) необходимо было просчитать стоимость всего периода, с условием выездов только по определенным дням. Заморачиваться с обходом результата не хотелось. Пришлось написать "Небольшой" запрос.

1 стартмани

03.03.2016    24462    2    Alexander.Shvets    5    

Простые радости жизни программиста 1С: выбор типа значения

Работа с интерфейсом Практика программирования v8 1cv8.cf Абонемент ($m)

Предлагаемая в работе обработка включает обычную и управляемую формы, которые максимально точно реализуют функциональность системного диалога выбора типа в толстом клиенте обычное приложение (включая оформление диалога). Эти формы имеют дополнительные интерфейсные удобства и могут быть использованы в качестве альтернативных диалогов выбора типа.

1 стартмани

17.02.2016    61598    56    yuraos    18    

Отображение прогресса выполнения длительных операций в БСП и их отладка в текущем сеансе.

БСП (Библиотека стандартных подсистем) Практика программирования v8 1cv8.cf Абонемент ($m)

В статье описан способ исполнения длительных операций в конфигурациях, в которых используется библиотека стандартных подсистем, с визуализацией прогресса исполнения и отображения хода обработки данных. Также дается краткое описание процесса отладки длительных операций в текущем сеансе.

1 стартмани

17.02.2016    73120    221    balanton    23    

Мастер рассылки e-mail 2.2 для управляемых форм

Email Практика программирования v8 v8::УФ ERP2 БП3.0 УТ11 Абонемент ($m)

Для пользователей: переделанный из старый разработки под 8.2 с использованием библиотеки Мастер рассылки e-mail 2.2 (ERP, УТ, БП) (Только управляемые формы), который теперь может запускаться под любой версией платформы с разрешенными или запрещенными модальными/синхронными вызовами в конфигурации. Также удобный выбор e-mail и их владельцев с помощью отбора динамического списка по любым критериям и галочки исключения.

1 стартмани

29.12.2015    48811    23    milkers    4    

Опять эти запросы...

Практика программирования v8 Абонемент ($m)

В статье описываются варианты построения выборки диапазона чисел или дат с помощью запроса. Рассматривается модифицированный вариант получения запросом среза остатков по регистру накопления или цен по регистру сведений на разные даты и производится сравнительный тест вариантов реализаций. Демонстрируется вариант реализации генерации нумерованных комбинаций свойств товара в запросе, по переданному набору перечня товара и его свойств.

1 стартмани

06.12.2015    21428    1    m..adm    41    

Передача больших пакетов через веб-сервисы

Инструменты администратора БД Внешние источники данных Практика программирования v8 Абонемент ($m)

Реализация механизма передачи больших пакетов через веб-сервисы. С его помощью передать файл размером в несколько гигабайт не составит проблем.

1 стартмани

06.12.2015    68568    56    YPermitin    19