Показать сообщение отдельно
Старый 20.12.2016, 17:45   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,873 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Angry Тормозит создание буфера.
Привет всем.
Обнаружил неприятную особенность виртуальных компаний.
Если табличка включена в виртуальную компанию то создание буфера может тормозить и занимать гигантское время (у нас до 1,2 миллисекунд).
Неважно каким способом создавать буфер.
common.data() // дублирование
dictTable.MakeRecord()
map.lookup() // достаем из мапа
conPeek(con, 1) // достаем из контейнера

Важно условие - длительность тормозов прямо зависит от числа компаний в системе (примерно линейная зависимость наблюдается). У нас 280 компаний - для такого количества порядка 1 миллисекунды торможение. Казалось бы немного но при работе с разными выгрузками когда обрабатываются десятки тысяч записей эти миллисекунды превращаются в минуты.

Интересно, что если буфер создавать в компании dat, которая не включена в виртуальную компанию, то все быстро. Т.е. глюк проявляется в зависимости от того в какой компании создается буфер.

Обнаружили случайно - была выгрузка остатков, которая в цикле перебирала мап из 20 тысяч элементов, на каждом шаге дочитывала настроечную табличку из 5 записей из БД. Решили оптимизировать - положили эти 5 записей в мап и стали брать из мапа, а оно стало медленнее работать раза в 2
Оказалось, что в наших условиях запрос к БД длился 0,5 миллисекунд, а создание нового буфера (при доставании из мапа) длилось 1,2 миллисекунды, что привело к замедление выгрузки секунд на 30.

Как можно это обойти:
1. Выкинуть буфер из виртуальной компании. (отключить saveDataPercompany для него и создать свое кастомизированное поле с кодом компании)
или
2. Постараться изменить код чтобы часто не создавать табличный буфер.
или
3. Если надо хранить данные буфера в мапе или другому подобном хранилище, то меняем мап с хранения табличных буферов на контейнеры и реализуем на буфере методы pack и unpack и работаем с буфером дальше. Только в процессе работы экземпляр таблички не пересоздаем а вызываем на нем unpack передавая в аргументы контейнер который достали из мапа.

P.S.
Проверял все на версии 2009 (воспроизводится на билдах ядра 1600.3596 и 1500.4570 (RU7))

Последний раз редактировалось Logger; 20.12.2016 в 17:52.
За это сообщение автора поблагодарили: Pustik (3), gl00mie (3), S.Kuskov (5), dech (3).