Медленное сложение строк #779314


#0 by PitNN
Добрый день, коллеги. Возникла непонятная ситуация. Сложение строк на тороне сервера происходит очень долго. Конкретно: Данная операция выполнившись 152899 раз заняла 72,663834 секунды и находится на первом месте в замере производительности. Вторая в списке тяжелых конструкций: Соответственно 152899 раз и 72,093324 секунд. Данное с Отдельное тестирование сложений тысячи строк из ста символов выдает что данная операция делается меньше секунды. С чем может быть связано подобное поведение?
#1 by Lexey_
с обращением через точку
#2 by Nuobu
С преобразованием типов.
#3 by PitNN
Не согласуется с второй строкой, когда обращения через точку отсутствует
#4 by PitNN
ИДПрайса Изначально имеет тип "Строка"
#5 by Nuobu
Отдельное тестирование сложений тысячи строк из ста символов выдает что данная операция делается меньше секунды. А теперь "меньше секунды" умножь на 152. Ибо ты тестировал тысячу, а у тебя - 152 000.
#6 by hitodom
сложение строк не сильная сторона 1с. попробуй записьтекста
#7 by PitNN
Неправильно написал, виноват. Там идет цикл 150000 раз. Собирается строка из строк по сто символов. На каждой тысячной итерации строка обнуляется. Вот это полное действие делается меньше секунды
#8 by WebberNSK
рекомендую почитать
#9 by PitNN
Вот часть кода: Как видно переменная ТекДатаВремя изначально имеет тип строка, но при этом Стр = стр + "', '" + ТекДатаВремя + "', '"; выполнившись 50000 раз затратило 29,4 секунд. Это к вопросу о приведении типов
#10 by PitNN
Спасибо, изучаю
#11 by Serginio1
#12 by Fragster
прав.
#13 by hitodom
А просто ЗаписьТекста хуже?
#14 by ptiz
Чем больше строка - тем дольше добавление.
#15 by ptiz
ЗаписьТекста (добавление без перевода строки) + ЧтениеТекста поможет
#16 by Мыш
Стр = Стр + "текст"; Особенности работы с памятью. Область памяти под переменную динамически увеличивается. Накладные расходы на эту операцию составляют основное время, имхо.
#17 by Fragster
вроде она через память не работает, а только через файл
#18 by Jija Grenkov
скорее всего нечего не увеличивается. Просто стр и "текст" теряют ссылки и уходят в муссор, а под новую итоговую строку выделятся нужный объем памяти. И так очень много раз. От чего сборщик муссора пыхтит. Скорее всего и процесс отъедает ядро проца полностью
#19 by Мыш
Тоже вариант. Точно только у разработчиков платформы узнать можно )
#20 by Fragster
стр = стр + стр в цикле очень быстро сжирает память, так как ищет непрерывный кусок для результата, даже сборщик мусора не помогает. ну и тормозит.
#21 by apokrit
Если версия платформы + режим совместимости позволяют, можно использовать СтрСоединить. Метод специально для этого и делали.
#22 by Serginio1
Здесь есть сравнение
#23 by DrZombi
Какая любопытненькая статейка :)
#24 by Мыш
Сравнил, кстати. ЗаписьXML и СтрСоединить сравнимы по скорости )
#25 by PitNN
Да, действительно, на первое место вылезли уже другие операции. Огромное спасибо) Как говорится век живи - век учись)
#26 by PitNN
Подскажите еще, пожалуйста. Что эффективнее, выполнение одной большой инструкции Соединение.Execute(ТекстЗапросовInsert); или нескольких поменьше?
#27 by Fragster
есть нюансы
#28 by Fragster
можно вообще отправить большой инсерт асинхронно и дальше работать
#29 by PitNN
Что за нюансы, подскажи пожалуйста
#30 by PitNN
Как это выглядит?
#31 by orefkov
Сборщик мусора в 1С? Отличные грибы!
#32 by b_ru
А что, в 1С его нету?
#33 by Смотрящий
Для начала покупаешь IIS
#34 by orefkov
Нет конечно. Только счётчик ссылок в каждом объекте. Память освобождается сразу при освобождении объекта. Циклические ссылки висят до смерти процесса.
#35 by aka AMIGO
Кто/Что заботится об очистке памяти? 1С? или всё-таки ОСь?
#36 by b_ru
Мне почему-то казалось, что это простейшая реализация сборки мусора, но да, по формальному определению оно ей не является :(
#37 by PitNN
Сделал отправку одного большого запроса на сервер. Стало быстрее чем несколько меньших
#38 by Jija Grenkov
получается и на сервере такой подход? Тогда понятно откуда неизбежные утечки памяти. Еще скорее всего нет никаких механизмов дефрагментации памяти так как этим обычно занимается GC По идее это было GC, если бы запускалось в отдельном процессе, а тут видимо interceptor в тех местах где пропадает ссылка. На сколько помню в objective C похожий подход.
#39 by Torquader
Это не сборка мусора, а процесс управления кучей памяти. Он ничего никуда не перемещает, а просто или выделяет память или освобождает. Что же касается строк, то упирается всё не в выделение памяти, а в копирование предыдущего значения строки, в новое место. Причём, со сложением строк в javascript те же "тапки" - тормозит так, что хочется в экран плюнуть.
#40 by Jija Grenkov
почти везде так будет где строки иммутабельны. К примеру в джаве есть мутабельная и иммутабельная строка.
#41 by Jija Grenkov
в JS можно использовать массив, должно быть быстрее
#42 by Torquader
Проблема в том, что когда складываешь две строки, нужно, чтобы под результат была выделена память - и в момент выделения памяти потребуется перенести блок данных из одного места в другое - всё равно будет memcpy только уже на уровне выделения памяти.
#43 by Jija Grenkov
не все так однозначо. Когда мы в цикле складываем 2 переменных типа строка и присваиваем - это значение 1-й переменной, } то выделяется область под результирующую строку куда копируються данные 2-х строк источников и так много раз. И GC тратит ресурс на освобождение памяти от 2-х исходных строк. Когда используется буфер, то в нем заранее выделена память под всю результирующую строку. В случае с JS некое подобие работы с буфером это создать массив где лежать все кусочки строки и 1 операцией сцепить все строки. В таком случае интерпритатору очень просто определить размер результирующей строки. var arr = [] arr.join("") ps. Сейчас браузеры пытаются оптимизировать 1й вариант и не везде получится увидеть разницу.
#44 by H A D G E H O G s
Сам то понял, что сказал?
#45 by Jija Grenkov
естественно, если не ясно детальное объяснение, скажу короче. В 1 варианте операций выделения памяти и сборки мусора больше.
#46 by Jija Grenkov
1 вариант: - В каждой итерации выделится и станет "муссором" память под "foo". - Каждую итерацию будет выделена и станет "муссором" память под состояние переменной "а". Размер переменной "а" будет увеличиваться с каждой итерацией. 2 вариант: - В каждой итерации выделится память под "foo". - 1 раз после цикла выделится память под итоговую строку после чего память выделенная под "foo" станет "муссором"
#47 by H A D G E H O G s
Проблема очистки стоит в этих ваших виртуальных машинах. В наших православных Дельфи проблемы очистки нет. Есть проблемы утечки. Которую контролят спецутилиты на этапе разработки. Что до строк, то есть 3 стратегии конкатенации: 1) Реаллокация на каждый чих 2) Программер сам знает (знает только программер, менеджер памяти никогда этого не знает) какой длины у него результирующая строка. Он выделяет память сразу и пишет в нее. Простейший пример BASE64 с ее 4/3 размером. 3) Мудрый менеджер памяти/среда разработки выделяет память под строки блоками, байт по 8000, к примеру, как это делает TStream в Дельфи. Самый годный вариант, кстати. Но я бы буфер сделал бы больше, по 64 Кбайта норм. Это все, что нужно знать в этой теме. Все остальное - лишнее.
#48 by Jija Grenkov
Обджект паскаль может и  был не плохим языком, но факт остается фактом, что этот ЯП самоликвидировался и именно из за конкуренции с языками работающими на виртуальной машине(java, c#). В джаве нет таких проблем, там и оптимизатор умный и девелопер может использовать StringBuilder и сам указать capacity этого билдера/буфера. Есть область памяти называемая пулом стрингов, где строки могут кешироваться и при повторном использовании литерала память не будет выделяться (в примере для JS под "foo" память выделится 1 раз) В джава так же есть возможность напрямую управлять памятью и эта память будет не под управлением виртуальной машине, мы такое в бигдате юзаем.
#49 by Garykom
Да удобство работы с динамическим выделением памяти в объектном паскале не очень по сравнению с Java/C#. Требует более высокого скилла прогов (как и C++), но конечный результат для пользователей чреват требованием апгрейда железа.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С