#0
by PitNN
Добрый день, коллеги. Возникла непонятная ситуация. Сложение строк на тороне сервера происходит очень долго. Конкретно: Данная операция выполнившись 152899 раз заняла 72,663834 секунды и находится на первом месте в замере производительности. Вторая в списке тяжелых конструкций: Соответственно 152899 раз и 72,093324 секунд. Данное с Отдельное тестирование сложений тысячи строк из ста символов выдает что данная операция делается меньше секунды. С чем может быть связано подобное поведение?
#5
by Nuobu
Отдельное тестирование сложений тысячи строк из ста символов выдает что данная операция делается меньше секунды. А теперь "меньше секунды" умножь на 152. Ибо ты тестировал тысячу, а у тебя - 152 000.
#7
by PitNN
Неправильно написал, виноват. Там идет цикл 150000 раз. Собирается строка из строк по сто символов. На каждой тысячной итерации строка обнуляется. Вот это полное действие делается меньше секунды
#9
by PitNN
Вот часть кода: Как видно переменная ТекДатаВремя изначально имеет тип строка, но при этом Стр = стр + "', '" + ТекДатаВремя + "', '"; выполнившись 50000 раз затратило 29,4 секунд. Это к вопросу о приведении типов
#16
by Мыш
Стр = Стр + "текст"; Особенности работы с памятью. Область памяти под переменную динамически увеличивается. Накладные расходы на эту операцию составляют основное время, имхо.
#18
by Jija Grenkov
скорее всего нечего не увеличивается. Просто стр и "текст" теряют ссылки и уходят в муссор, а под новую итоговую строку выделятся нужный объем памяти. И так очень много раз. От чего сборщик муссора пыхтит. Скорее всего и процесс отъедает ядро проца полностью
#20
by Fragster
стр = стр + стр в цикле очень быстро сжирает память, так как ищет непрерывный кусок для результата, даже сборщик мусора не помогает. ну и тормозит.
#21
by apokrit
Если версия платформы + режим совместимости позволяют, можно использовать СтрСоединить. Метод специально для этого и делали.
#25
by PitNN
Да, действительно, на первое место вылезли уже другие операции. Огромное спасибо) Как говорится век живи - век учись)
#26
by PitNN
Подскажите еще, пожалуйста. Что эффективнее, выполнение одной большой инструкции Соединение.Execute(ТекстЗапросовInsert); или нескольких поменьше?
#34
by orefkov
Нет конечно. Только счётчик ссылок в каждом объекте. Память освобождается сразу при освобождении объекта. Циклические ссылки висят до смерти процесса.
#36
by b_ru
Мне почему-то казалось, что это простейшая реализация сборки мусора, но да, по формальному определению оно ей не является :(
#38
by Jija Grenkov
получается и на сервере такой подход? Тогда понятно откуда неизбежные утечки памяти. Еще скорее всего нет никаких механизмов дефрагментации памяти так как этим обычно занимается GC По идее это было GC, если бы запускалось в отдельном процессе, а тут видимо interceptor в тех местах где пропадает ссылка. На сколько помню в objective C похожий подход.
#39
by Torquader
Это не сборка мусора, а процесс управления кучей памяти. Он ничего никуда не перемещает, а просто или выделяет память или освобождает. Что же касается строк, то упирается всё не в выделение памяти, а в копирование предыдущего значения строки, в новое место. Причём, со сложением строк в javascript те же "тапки" - тормозит так, что хочется в экран плюнуть.
#40
by Jija Grenkov
почти везде так будет где строки иммутабельны. К примеру в джаве есть мутабельная и иммутабельная строка.
#42
by Torquader
Проблема в том, что когда складываешь две строки, нужно, чтобы под результат была выделена память - и в момент выделения памяти потребуется перенести блок данных из одного места в другое - всё равно будет memcpy только уже на уровне выделения памяти.
#43
by Jija Grenkov
не все так однозначо. Когда мы в цикле складываем 2 переменных типа строка и присваиваем - это значение 1-й переменной, } то выделяется область под результирующую строку куда копируються данные 2-х строк источников и так много раз. И GC тратит ресурс на освобождение памяти от 2-х исходных строк. Когда используется буфер, то в нем заранее выделена память под всю результирующую строку. В случае с JS некое подобие работы с буфером это создать массив где лежать все кусочки строки и 1 операцией сцепить все строки. В таком случае интерпритатору очень просто определить размер результирующей строки. var arr = [] arr.join("") ps. Сейчас браузеры пытаются оптимизировать 1й вариант и не везде получится увидеть разницу.
#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С
В этой группе 1С
- Как объединить ячейки в табличной части?
- А как узнать, что у пользователя интерфейс такси?
- Корректировка выпуска продукции (услуг) Дт 41.01 Кт 20.01 с минусовой суммой
- 1С Розница, у товара две цены
- ЗУП 2.5 - Почему при создании сотрудника открывается форма помощника?
- Свойство "ВыделенныеСтроки" не корректно возращает идентификатор строки.
- Конвертация данных. Синхронизация договоров
- Алгоритм размазывания суммы ХХХХ по ТЧ документа
- Подключение по com в клиент-серверном варианте
- v7: Скорость загрузки 1с77
- Печать HTML документ через подсистему печати БСП
- УТ 11 Номенклатура, продаваемая совместно
- Способы распределения статей затрат организаций
- Зарплата в УПП 1.3
- Обмен данными через конвертацию данных
- можно ли использовать видеоочки вместо монитора и почему ?
- Подписка на событие "ПриЗаписи" или "ПередЗаписью" для регистра накопления.
- Как строку закодировать в hex-кодировке
- 1С:Документооборот, как запретить создавать процесс для незарегистрированного
- БГУ 1.0 Розничные продажи