AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
DAX
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 29.11.2011, 16:01   #21  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
Лучший по профессии 2017
Лучший по профессии 2015
 
3,624 / 1817 (68) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от someOne Посмотреть сообщение
Мммда... С 2005 года - могли бы десять раз поправить уже. Мне казалось что люди из команды разработчиков Аксапта читают этот форум... Жаль. Может теперь заметят ?
единственный способ это исправить - зарегистрировать соответствующий запрос в поддержке
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: Logger (1).
Старый 29.11.2011, 17:31   #22  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,198 / 341 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
Вставлю свои 5 копеек про таблицу TaxTrans без индекса и крайне тормозной расчет "Налога 1099" : Загрузка строк Purchase order
За это сообщение автора поблагодарили: Logger (3), someOne (3).
Старый 29.11.2011, 21:25   #23  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от fed Посмотреть сообщение
...
Однако есть одна загводка: Как известно, временные таблицы хранятся в памяти только если их размер не превышает 128 КБайт. Если размер превысил эту величину, то AOS выгружает их во временный файл, запросами и доступом к которому занимается сам AOS. А внутренний процессор запросов в AOS не быстрый и не оптимизировали его с прошлого столетия, вероятно он часто в fullscan скатывается
Размер одной записи в tmpTaxWorkTrans в стандартной конфигурации, составляет 793 байта. Получается что где-то после 160 строк в заказе/закупке, данные из таблицы выгружаются на диск и начинают страшно тормозить в запросах.

Если в новой версии (2012) tmpTaxWorkTrans переделали в SQL-ную временную таблицу, это должно заметно ускорить процесс. Также можно надеятся, что в 64битной версии сервера (а мне кажется 32битной и не будет) наконец-то отменили ограничение в 128 Кбайт под временную таблицу в памяти и теперь таблица будет храниться в памяти пока таковая имеется.
Кстати такой вариант оптимизации времянок мы попробовали.
Идея в том, чтобы заставить времянки создаваться в памяти.
Например, можно завести виртуальный диск, реально живущий в памяти и прописать его в переменную окружения как темповую папку для пользователя, под которым работает сервер приложения. В таком случае файлы *.$$$, содержащие времянки будут реально жить в памяти и работать быстро. К сожалению, это не решило всех проблем. Если поиск во времянке делать по неиндексированному полю, то время улучшается примерно в 6-7 раз. Если по индексированному, то в 2 раза. (Т.е. индексы на больших времянках тоже существенно влияют на скорость) Также примерно в 2 раза ускоряется операция вставки. Мы ожидали бОльшего ускорения, поэтому на боевой базе не стали это применять.

Тест проводили на примерно 100-200 тысячах записей буферов UnitConvert. Это составило примерно 50-100 мегабайт в $$$ файле на диске.
За это сообщение автора поблагодарили: S.Kuskov (5).
Старый 03.02.2022, 20:32   #24  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 19.09.2007
Я тут в очередной раз занимался оптимизацией разноски розничных продаж и наткнулся еще на пару возможных улучшений.
1. Метод writeTaxAmount_W, который тут ранее оптимизировали вызывает в цикле метод CustVendInvoiceTrans.initFromTaxWorkTrans_RU(). Там выполняется неиндексируемый запрос к злосчастной темповухе TmpTaxWorkTrans. Единственный селективный фильтр там это номер лота InventTransId, но индекса по нему нету. Получается примерно такая трассировка
Нажмите на изображение для увеличения
Название: trace.jpg
Просмотров: 23
Размер:	109.0 Кб
ID:	13298
В общем нужно добавить индекс и плюс пришлось еще поменять немного код на поиске.
X++:
    if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoRU]))
    {
        //+ sergey.m 03.02.2022 FRE_20421639_001
        if (!_sourceRecId)
        {
            select taxWorkTrans index hint InventTransIdx
                where taxWorkTrans.SourceTableId == _sourceTableId       &&
                      taxWorkTrans.InventTransId == _inventTransId       &&
                      taxWorkTrans.TaxDirection  != TaxDirection::UseTax &&
                      taxWorkTrans.TaxOrigin     != TaxOrigin::TaxReversed;
        }
        else
        {
        //- sergey.m 03.02.2022 FRE_20421639_001
            select taxWorkTrans
                where taxWorkTrans.SourceTableId  == _sourceTableId             &&
                      ((_sourceRecId &&
                        taxWorkTrans.SourceRecId == _sourceRecId) ||
                       (! _sourceRecId &&
                        taxWorkTrans.InventTransId == _inventTransId))          &&
                      taxWorkTrans.TaxDirection       != TaxDirection::UseTax   &&
                      taxWorkTrans.TaxOrigin          != TaxOrigin::TaxReversed;
        }
Хинт на inMemory срабатывает. Без него у меня улучшений не было. Не знаю как тут аксапта выбирает какой индекс использовать, думаю хватает первый попавшийся по совпадению поля.

2. В классе Tax метод lineTaxAmount. В начале метода проверяется что в таблице есть записи немного экзотическим методом, считая их количество. Я поменял так, хотя можно было наверное вообще убрать запрос, меня пока и так устраивает.
X++:
    if (this.taxParameters().TaxSpecifyLine)
    {
    if (this.taxParameters().TaxSpecifyLine)
    {
        //+ sergey.m 03.02.2022 FRE_20421639_001
        //select count(RecId) from taxWorkTrans;
        select firstOnly RecId from taxWorkTrans;
        //- sergey.m 03.02.2022 FRE_20421639_001

        if (taxWorkTrans.RecId > 0 && !this.useSubLedgerJournalLines())
        {
            // Posting out of TmpTaxWorkTrans
Еще тормозит российская корреспонденция фин. проводок. Так не хочется глубоко погружаться в это. Никто не правил случаем? Я там кое-что правил, но вот этот кошмар остался. Без единового вызова субд.

Нажмите на изображение для увеличения
Название: trace1.jpg
Просмотров: 24
Размер:	107.8 Кб
ID:	13299
За это сообщение автора поблагодарили: Logger (5), trud (10).
Старый 03.02.2022, 21:03   #25  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Masel Посмотреть сообщение
Еще тормозит российская корреспонденция фин. проводок. Так не хочется глубоко погружаться в это. Никто не правил случаем? Я там кое-что правил, но вот этот кошмар остался. Без единового вызова субд.
Для какой версии ?
Я для 2009-й кое что правил - некие частные случаи с накладными расходами.
Там проблема из-за нелинейной зависимости от числа строк при разноске. (где то на форуме была тема)

Где возможно -
1. отключали корреспонденцию.
2. для больших документов (более 300 строк) вместо одной накладной делали кучку накладных по 40 строк. тем самым линеаризовали зависимость времени разноски от числа строк. - у нас были компании для управленческого учета где число накладных было неважно, главное итоговые показатели. Вот там такое было применимо.
Старый 03.02.2022, 21:22   #26  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 19.09.2007
Цитата:
Сообщение от Logger Посмотреть сообщение
Для какой версии ?
2012 R2. Подозреваю что существенно не поменялось с 2009. В CIL то оно еще сносно работает, но все равно бы хотелось оптимизировать. Там явно неэффективные эти пробеги по map бесконечные.
Старый 03.02.2022, 22:10   #27  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
а, так вот пример
Оптимизация класса Tax

ну можно что-то аналогичное сделать.

Вообще код сложный. Стремно что-то менять.
Может разноску в ГК разбить на куски - сгруппировать по N строк. Уйдут нелинейные эффекты.
Я думаю так в итоге проще будет и безопаснее. Меньше вероятности что-то сломать. Обновления проще поднять.

Про нелинейность:
Как линейное время превращается в Windows в O(n²)
Старый 03.02.2022, 22:12   #28  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Masel Посмотреть сообщение
В CIL то оно еще сносно работает, но все равно бы хотелось оптимизировать. Там явно неэффективные эти пробеги по map бесконечные.
В CIL быстрее за счет двух вещей
1. JIT (ну и в целом CIL шустрее чем p-code)
2. Асинхронный сборщик мусора.
Старый 03.02.2022, 22:42   #29  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Masel Посмотреть сообщение
Там явно неэффективные эти пробеги по map бесконечные.
Да!
Да!

Это прямо бросается в глаза. Перебор всего мапа со сравнением со значением на каждом шаге. Очень неэффективный поиск значения сделан. Видимо автор закладывался на то что раз операция в памяти то все будет быстро. Как бы не так! Там слишком много элементов в мапе на большом числе строк документа получается.
Поскольку там не голый мап а класс обертка, то у меня была идея сделать в нем некий вспомогательный второй мап, который будет индексом к основному мапу и позволит не перебирать все элементы первого мапа для поиска значений. Но руки не дошли.
Старый 03.02.2022, 22:43   #30  
EVGL is offline
EVGL
Moderator
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,404 / 3006 (109) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Бессмысленное занятие. В D365 все уходит в microservice с закрытым кодом, а для индийского GST они в Москве все давно перекроили на решение систем линейных уравнений, кажется.

https://docs.microsoft.com/en-us/dyn...ion-service-ga

П.с. говорит автор. Моя работа
Думаю, вы правы. На этапе merge я, кажется, проверял соответствие ряда характеристик LedgerVoucherTransObject, как то: счет ГК, аналитики, тип проводки, сторона дебет/кредит. Наверное, из них можно было собрать hash key. Тогда (2002) такого pattern не было.

Последний раз редактировалось EVGL; 03.02.2022 в 22:51.
За это сообщение автора поблагодарили: Logger (3).
Старый 03.02.2022, 23:00   #31  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от EVGL Посмотреть сообщение
Бессмысленное занятие.
Бессмысленное, если в ближайшем будущем планировать переход на 365ю.
Старый 04.02.2022, 08:51   #32  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
352 / 513 (18) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от Masel Посмотреть сообщение
Я тут в очередной раз занимался оптимизацией разноски розничных продаж и наткнулся еще на пару возможных улучшений.
1. Метод writeTaxAmount_W, который тут ранее оптимизировали вызывает в цикле метод CustVendInvoiceTrans.initFromTaxWorkTrans_RU(). Там выполняется неиндексируемый запрос к злосчастной темповухе TmpTaxWorkTrans. Единственный селективный фильтр там это номер лота InventTransId, но индекса по нему нету. Получается примерно такая трассировка
На уровне идеи (не факт конечно, что будет быстрее) - можно же вообще убрать запрос в этом месте к темповой табличке для RU функциональности(наверное и в общем случае можно, но будет чуть сложнее), я может конечно что то забываю или не учитываю, но идея такая :

- на одну строку накладной одна запись в TmpTaxWorkTrans для RU, связь по номеру лота (по логике можно хранить и несколько записей, но кажется в этом случае особого профита по сравнению с индексом не будет)

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

- в цикле из мапа получать запись TmpTaxWorkTrans и ее отдавать в метод уже (в самом методе и чуть ниже придется поменять код, так что обрабатывать запись, а не курсор, но это не кажется сложным).
__________________
Sergey Nefedov
Старый 04.02.2022, 11:28   #33  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 19.09.2007
Цитата:
Сообщение от SRF Посмотреть сообщение
На уровне идеи (не факт конечно, что будет быстрее) - можно же вообще убрать запрос в этом месте к темповой табличке для RU функциональности(наверное и в общем случае можно, но будет чуть сложнее), я может конечно что то забываю или не учитываю, но идея такая :

- на одну строку накладной одна запись в TmpTaxWorkTrans для RU, связь по номеру лота (по логике можно хранить и несколько записей, но кажется в этом случае особого профита по сравнению с индексом не будет)

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

- в цикле из мапа получать запись TmpTaxWorkTrans и ее отдавать в метод уже (в самом методе и чуть ниже придется поменять код, так что обрабатывать запись, а не курсор, но это не кажется сложным).
Не факт что там одна запись, индексов уникальных нет и выбирется курсор без firstonly, внутри они его фетчат, делают next TmpTaxWorkTrans. Поэтому придется делать map InventTransId -> Set(Types::record) и потом внутри логику менять, чтобы он заместо фетча бегал по Set. Это можно сделать, но в моем сценарии нет смысла, т.к. индексированный поиск отрабатывает меньше милисекунды.
Старый 08.02.2022, 09:07   #34  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 19.09.2007
Оптимизировал все таки корреспонденцию. Тестовый пример заказ на 2770 строк. В CIL выигрыш в абсолютном выражении не большой: время сократилось с 1,5 минут до 18 секунд. А в p-code c 20 минут до 1 мин 35сек. Медленно работало объединение списков ссылок на проводки TaxTrans при суммировании проводок ГК в корреспонденции. Это делалось поэлементно, переделал на контейнеры.
Вложения
Тип файла: xpo Class_LedgerBondMergeablesGeneralJour_RU.xpo (14.6 Кб, 44 просмотров)
За это сообщение автора поблагодарили: Logger (10), mazzy (10).
Старый 08.02.2022, 13:30   #35  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,669 / 2588 (94) +++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Masel Посмотреть сообщение
Оптимизировал все таки корреспонденцию...
А можете выложить некастомизированную, стандартную версию класса для вашей версии приложения ?
Думаю это поможет тем кто захочет портировать на 2009-ю версию.

Плюс с R3 тоже есть незначительные отличия.
Старый 08.02.2022, 13:59   #36  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 19.09.2007
Исходная с R2 во вложении.
Вложения
Тип файла: xpo Class_LedgerBondMergeablesGeneralJour_RU.xpo (9.3 Кб, 33 просмотров)
Старый 08.02.2022, 19:29   #37  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4475 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Masel Посмотреть сообщение
Оптимизировал все таки корреспонденцию. Тестовый пример заказ на 2770 строк. В CIL выигрыш в абсолютном выражении не большой: время сократилось с 1,5 минут до 18 секунд. А в p-code c 20 минут до 1 мин 35сек. Медленно работало объединение списков ссылок на проводки TaxTrans при суммировании проводок ГК в корреспонденции. Это делалось поэлементно, переделал на контейнеры.
1.
Спасибо!

2.
Для длинных коллекций в Аксапте вместо контейнеров лучше использовать List.
Контейнер только в 2012 и только в CIL реализован на базе System.Array
в младших версиях и в p-code контейнер реализован на базе строки.

3.
смотрите что сейчас у вас получается.
3.1. вы получаете коллекцию taxTransactionRelationshipCollection
3.2. эта коллекция по сути дела является Map(Key:RecId, Value:Set{Enum})
3.3. вы перекладываете этот map в 4 ваших контейнера (кстати, enum'ов больше, чем 4)
3.4. а в методе taxTransactionRelationshipCollection() вы перекладываете ваши контейнеры в новую коллекцию taxTransactionRelationshipCollection.

вопрос: а зачем вообще нужна эта перекладка из мапы в контейнер и наоборот?
добавьте метод merge в класс LedgerPostingOneToManyCollection и пользуйтесь доступом непосредственно к методам мапы и множества - insert, lookup, in, add. Получится и проще для понимания и быстрее.

вопрос: а зачем вообще нужна мапа, состоящая из множеств? для которой нужно реализовывать операции с каждым элементом.

Если уж решились оптимизировать - используйте временную таблицу.
тогда сложение двух коллекций будет реализовано оператором insert_recordset.

Причем используйте временную таблицу прямо внутри класса LedgerPostingOneToManyCollection.
Оставьте внешний интерфейс класса неизменным, а внутреннюю реализацию сделайте на временной таблице.

------------------------------------
Скорее всего, классы LedgerPostingOneToManyCollection и LedgerBondMergeablesGeneralJour_RU реализовывали разные люди.
И русские скорее всего не могли вставиться в LedgerPostingOneToManyCollection по огранизационным причинам.
Но вы то можете.

Обратите внимание насколько код в 2012 НЕ использует возможности таблиц и возможности СУБД. Бегут как чёрт от ладана. Всякую херню в памяти делают, лишь бы не таблицы.
Но вы то не такие. Правда?
------------------------------------

и... фу, какие душные названия в ax2012.
Миниатюры
Нажмите на изображение для увеличения
Название: ax01.PNG
Просмотров: 37
Размер:	109.9 Кб
ID:	13310   Нажмите на изображение для увеличения
Название: ax02.PNG
Просмотров: 43
Размер:	96.4 Кб
ID:	13311  

Изображения
 
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 08.02.2022 в 19:41.
Старый 08.02.2022, 20:58   #38  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 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).
Старый 08.02.2022, 23:53   #39  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4475 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Masel Посмотреть сообщение
На R2 в енуме 4 значения. У вас их больше либо потому, что R3, либо потому, что добавлено на USR слое.
R3

Цитата:
Сообщение от Masel Посмотреть сообщение
Вы в принципе не совсем понимаете в чем затыки по производительности в этом месте


Цитата:
Сообщение от Masel Посмотреть сообщение
У нас есть большое количество кусочков проводок ГК по налогам, образованные каждой строкой заказа на продажу.
угу. "кусочки" в английской аксапте называются movements.
по-русски, их можно называть "движения".

Цитата:
Сообщение от Masel Посмотреть сообщение
То есть она создает абсолютно новую структуру данных и переваливает потом все элементы в цикле по одному. В пером параметре _first куча элементов, во втором немного.
Угу.

Цитата:
Сообщение от Masel Посмотреть сообщение
Здесь идеально бы работало просто

X++:
this.addCollections(_first, _second);
return _first;
Но тогда вы измените taxTransactionRelationshipCollection на которую ссылаются из других мест.
Угу-угу.

Цитата:
Сообщение от Masel Посмотреть сообщение
В целом по коду кажется что после суммирования старый экземпляр LedgerBondMergeablesGeneralJour_RU уже использоваться не будет, но я так делать не решился.
угу-угу-угу.
авторы россикского класса вот тоже побоялись.

Цитата:
Сообщение от Masel Посмотреть сообщение
Далее встает вопрос, как переделать так, чтобы оставить такой подход - два элемента скопировать в первый, но сделать это быстро.

Нужно что-то типа _first.Clone(). Но такого метода ни у Map, ни у Set нету. pack/unpack не решают задачу.
tmpTable.setTmpData(fromTmpTable);



по поводу pack/unpack создал отдельную тему
List/Set/Map/Array: deep clone через pack/create в классических Аксаптах


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

но решить можно еще лучше.

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

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

Подумайте - а что если бы метод merge существовал прямо в классе с идиотским назвнием LedgerPostingOneToManyCollection?

Цитата:
Сообщение от Masel Посмотреть сообщение
По поводу идеи с таблицей. Будет тормозить еще больше я думаю, хотя не пробовал. В CIL точно больше.
Подумайте
Подумайте не только об этом месте.

Ведь по сути, данное место просто окрашивает движения разными enum-признаками. Рано или поздно эти признаки надо будет как-то связать с исходными движениями.

Поскольку сейчас признаки хранятся в коллекции, то надо будет снова делать цикл по одному и искать исходные движения по одному.
А можно было бы сделать select-join со временной таблицей

Похоже, что беда в том, что данный код класса с идиотским названием делал человек, который не знает ни аксапту, ни СУБД. Причем, этот код прошел ревью. Т.е. либо это был team lead, который может впендюрить код без ревью, либо вся команда была уровня "не знаю ни аксапту, ни СУБД". И я даже не знаю какой вариант хуже...

Цитата:
Сообщение от Masel Посмотреть сообщение
Вместо 4 контейнеров можно было сделать один, который бы хранил и RecId и enum.
а можно map как в исходном классе с идиотским названием LedgerPostingOneToManyCollection

Цитата:
Сообщение от Masel Посмотреть сообщение
Можно еще как-то по другому делать, например я думал использовать структуры .Net.
это только для CIL.
между p-code и .net слишком дорогой маршаллинг.

Цитата:
Сообщение от Masel Посмотреть сообщение
Или, возможно если оставить эти пробеги в циклах по Map, но просто убрать Set, то этого будет достаточно (заменить Map recId -> Set, на более простую структуру данных).
угу. таблицу, например

Цитата:
Сообщение от Masel Посмотреть сообщение
Но меня просто устраивает этот вариант, я его замерил, если знаете как лучше, то сделайте, только проверьте результат по времени работы.
Если устраивает, то нет вопросов, конечно.

Огромное спасибо за предложенное решение.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 09.02.2022 в 00:10.
Старый 09.02.2022, 11:51   #40  
Masel is offline
Masel
Участник
 
37 / 504 (17) +++++++
Регистрация: 19.09.2007
Цитата:
Сообщение от mazzy Посмотреть сообщение
tmpTable.setTmpData(fromTmpTable);
Это не дублирование, вы просто получите вторую ссылку на тот же экземпляр таблицы.

Цитата:
Сообщение от mazzy Посмотреть сообщение
Подумайте - а что если бы метод merge существовал прямо в классе с идиотским назвнием LedgerPostingOneToManyCollection
Я если честно не понимаю просто эту идею, что это даст.
За это сообщение автора поблагодарили: S.Kuskov (5).
Теги
faq, tax, налоги, оптимизация, производительность

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Вызов метода базового класса Eldar9x DAX: Программирование 15 22.03.2008 19:10
jerry-dynamics: tax codes Blog bot DAX Blogs 0 16.06.2007 11:20
Вызов класса из другого класса Protey DAX: Программирование 9 26.02.2007 11:01
передача курсора в два класса kitty DAX: Программирование 3 09.08.2006 13:21
Запустить метод класса loka DAX: Программирование 2 13.03.2006 15:40
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 03:30.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.