Показать сообщение отдельно
Старый 08.02.2022, 20:58   #38  
Masel is offline
Masel
Участник
 
39 / 527 (18) +++++++
Регистрация: 19.09.2007
Цитата:
Сообщение от mazzy Посмотреть сообщение
Для длинных коллекций в Аксапте вместо контейнеров лучше использовать List.
Контейнер только в 2012 и только в CIL реализован на базе System.Array
в младших версиях и в p-code контейнер реализован на базе строки.
List здесь не подходит, потому что его нельзя быстро клонировать. pack/unpack вызывает ту же многократную вставку. Я это проверял.

Цитата:
Сообщение от mazzy Посмотреть сообщение
3.3. вы перекладываете этот map в 4 ваших контейнера (кстати, enum'ов больше, чем 4)
На R2 в енуме 4 значения. У вас их больше либо потому, что R3, либо потому, что добавлено на USR слое.


Вы в принципе не совсем понимаете в чем затыки по производительности в этом месте (может в ваших сценариях их просто нет). У нас есть большое количество кусочков проводок ГК по налогам, образованные каждой строкой заказа на продажу. Дальше упрощая система бежит по этим кусочкам и прибавляет их к первой проводке, получается как бы нарастающий итог. В моем случае все эти проводки сворачиваются в итоге всего в 2 проводки по налогам, вроде на продажи и возвраты (точно не разбирался, вторая с минусом). Кроме суммирования самих полей проводки еще объединяются ссылки на taxTrans, это recid. Поэтому типичная ситуация, когда к проводке, у которой уже 7000 ссылок прибавляется одна по которой 1 ссылка. Система это делает следующим образом:
X++:
    #define.IgnoreDuplicates(true)
    LedgerPostingOneToManyCollection ret = LedgerPostingOneToManyCollection::construct(
        Types::Int64, // use this instead of RecId for perf
        Types::Enum,
        #IgnoreDuplicates);

    this.addCollections(ret, _first);
    this.addCollections(ret, _second);
То есть она создает абсолютно новую структуру данных и переваливает потом все элементы в цикле по одному. В пером параметре _first куча элементов, во втором немного. Здесь идеально бы работало просто

X++:
this.addCollections(_first, _second);
return _first;
Но тогда вы измените taxTransactionRelationshipCollection на которую ссылаются из других мест. Там есть целый класс, который еще раз ссылается на все эти свойства и хранит их ID. В целом по коду кажется что после суммирования старый экземпляр LedgerBondMergeablesGeneralJour_RU уже использоваться не будет, но я так делать не решился.

Далее встает вопрос, как переделать так, чтобы оставить такой подход - два элемента скопировать в первый, но сделать это быстро. Нужно что-то типа _first.Clone(). Но такого метода ни у Map, ни у Set нету. pack/unpack не решают задачу.

В качестве решения предлагается изменить структуру хранения так, чтобы дублирование выполнялось командой container1 = container2, это работает быстро. А для того, чтобы изменить интерфейс работы с классом модифицировать taxTransactionRelationshipCollection метод, чтобы он выдавал данные в привичном виде, собирая из контейнеров результат.

Сценарий работы с этим классом такой.
1) Вначале экземпляры создаются по каждой микропроводке по строке заказа методом initFromLedgerVoucherTransObject
2) Все многократно мерджится, используется метод merge, вызывается много раз
3) По просуммированным проводкам вызывается 1 раз метод taxTransactionRelationshipCollection по каждой проводке. У меня проводки 2, соответственно вызывается он по налогам 2 раза.

Поэтому оптимизируем вызовы merge.

По поводу идеи с таблицей. Будет тормозить еще больше я думаю, хотя не пробовал. В CIL точно больше.
Вместо 4 контейнеров можно было сделать один, который бы хранил и RecId и enum. Но он был бы в 2 раза больше. У меня в примере например значение енума Offset всегда, соответственно только 1 полный контейнер.
Можно еще как-то по другому делать, например я думал использовать структуры .Net. Или, возможно если оставить эти пробеги в циклах по Map, но просто убрать Set, то этого будет достаточно (заменить Map recId -> Set, на более простую структуру данных). Но меня просто устраивает этот вариант, я его замерил, если знаете как лучше, то сделайте, только проверьте результат по времени работы.

Последний раз редактировалось Masel; 08.02.2022 в 21:35.
За это сообщение автора поблагодарили: mazzy (10).