08.09.2011, 12:11 | #1 |
Участник
|
axperf: Improvements on the global methods buf2con and con2buf in Microsoft Dynamics AX 2012
Источник: http://blogs.msdn.com/b/axperf/archi...s-ax-2012.aspx
============== The global methods buf2con and con2buf are used on X++ to convert table buffers into containers and vice versa. New functionality has been added to these methods and they had been improved to be much faster than their implementation on previous versions...(read more) Источник: http://blogs.msdn.com/b/axperf/archi...s-ax-2012.aspx
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
09.09.2011, 01:18 | #2 |
Участник
|
Интересно, кто-то замерял производительность старых и новых методов?
|
|
16.02.2017, 17:46 | #3 |
Участник
|
Как раз искал ответ на этот вопрос.
Провел замеры сам. Во вложении джобики, которыми замерял, примерно такого вида X++: static void testPackSpeed_02(Args _args) { int64 tickFrom; int64 tickTo; int i; // int iMax = 10000; int iMax = 20000; SalesTable salesTable; container con; ; select salesTable order by RecId; //tickFrom = WinAPI::getTickCount64(); tickFrom = WinAPI::getTickCount(); for (i = 1; i <= iMax; i++) { con = salesTable.buf2con(false); // дефолтное поведение в 2012-й } tickTo = WinAPI::getTickCount(); info(strFmt("Способ упаковки salesTable.buf2con(false) время %1 млсек для %2 вызовов. На один вызов %3 млсек", tickTo - tickFrom, iMax, strLRTrim(num2str((tickTo - tickFrom)/iMax, 16, 6, 2, 0)) )); } Сравнивали скорость упаковки такими способами con = salesTable.buf2con(false); con = salesTable.buf2con(true); con = [salesTable]; Global::buf2ConOLD2009(salesTable) и распаковки такими способами salesTable.con2buf(con) Global::con2Buf(con, salesTable); salesTable = Global::con2Buf(con); salesTable = conPeek(con, 1); [salesTable] = con; Global::con2BufOLD2009(con, salesTable); где Global::buf2ConOLD2009 Global::con2BufOLD2009 это методы Global::buf2Con Global::con2Buf взятые из 2009-й код методов такой: X++: static container buf2ConOLD2009(Common common) { container c = [common.TableId]; DictTable dictTable = new DictTable(common.TableId); fieldId fieldId = dictTable.fieldNext(0); DictField dictField; ; while (fieldId) { dictField = new DictField(common.TableId,fieldId); if(dictField.baseType() == Types::Container) c += [common.(fieldId)]; else c += common.(fieldId); fieldId = dictTable.fieldNext(fieldId); } return c; } X++: static void con2BufOLD2009(container c, Common common) { fieldId fieldId; int i; DictTable dictTable; if (common.TableId == conpeek(c,1)) { dictTable = new DictTable(common.TableId); fieldId = dictTable.fieldNext(0); i = 2; while (fieldId) { //common.(fieldId) = conpeek(c,i); common.(fieldId)[1] = conpeek(c,i); // array fix i++; fieldId = dictTable.fieldNext(fieldId); } } } Последний раз редактировалось Logger; 16.02.2017 в 17:57. |
|
16.02.2017, 17:56 | #4 |
Участник
|
Результат такой
Цитата:
Способ упаковки salesTable.buf2con(false) время 2937 млсек для 20000 вызовов. На один вызов 0,146850 млсек
Способ распаковки salesTable.con2buf(con); (упакован buf2con(false)) время 813 млсек для 20000 вызовов. На один вызов 0,040650 млсек Способ распаковки Global::con2Buf(con, salesTable); (упакован buf2con(false)) время 1328 млсек для 20000 вызовов. На один вызов 0,066400 млсек Способ распаковки salesTable = Global::con2Buf(con); (упакован buf2con(false)) время 1938 млсек для 20000 вызовов. На один вызов 0,096900 млсек Способ упаковки salesTable.buf2con(true) время 5453 млсек для 20000 вызовов. На один вызов 0,272650 млсек Способ распаковки salesTable.con2buf(con); (упакован buf2con(true)) время 1437 млсек для 20000 вызовов. На один вызов 0,071850 млсек Способ распаковки Global::con2Buf(con, salesTable); (упакован buf2con(true)) время 1984 млсек для 20000 вызовов. На один вызов 0,099200 млсек Способ распаковки salesTable = Global::con2Buf(con); (упакован buf2con(true)) время 2516 млсек для 20000 вызовов. На один вызов 0,125800 млсек Способ упаковки con = [salesTable] время 5500 млсек для 20000 вызовов. На один вызов 0,275000 млсек Способ распаковки salesTable = conPeek(con, 1); (упакован con = [salesTable]) время 750 млсек для 20000 вызовов. На один вызов 0,037500 млсек Способ распаковки [salesTable] = con; (упакован con = [salesTable]) время 734 млсек для 20000 вызовов. На один вызов 0,036700 млсек Способ упаковки Global::buf2ConOLD2009(salesTable); время 118531 млсек для 20000 вызовов. На один вызов 5,926550 млсек Способ распаковки Global::con2BufOLD2009(con, salesTable); (упакован con = Global::buf2ConOLD2009(salesTable)) время 52110 млсек для 20000 вызовов. На один вызов 2,605500 млсек |
|
16.02.2017, 18:07 | #5 |
Участник
|
Основные выводы :
1. Старый способ упаковки-распаковки через X++ методы (как в Global классе 2009-й версии) никуда не годятся и тормозят (примерно в 100 раз медленнее чем методы ядра). Ну это и так было очевидно. 2. Способ упаковки/распаковки con = [salesTable] salesTable = conPeek(con, 1) [salesTable] = con очень быстрый - примерно такой же по скорости как и новые методы ядра введенные в 2012-й версии. (Правда содержит неприятный баг при упаковке наследуемых табличек. Подробности тут sashanazarov: Table inheritance and collection objects) В связи с этим непонятно чем так гордились (https://blogs.msdn.microsoft.com/axp...amics-ax-2012/) разработчики ядра 2012-й версии - время упаковки распаковки практически не изменилось. Или они сравнивали с x++ методами ? 3. С учетом наличия багов в 2012-й версии лучше использовать новый метод (вызовы con2buf и buf2con прямо на буфере). 4. В 2012-й вызов Global::con2Buf() может раза в 1,5-2 проигрывать по скорости вызову buffer.conbuf() (вероятно из-за пересоздания объектов и обращения к Dict классам) 5. Если наследования табличек нет, то при переходе с 2009-й на 2012-ю можно оставить старый способ паковки распаковки буферов в контейнер (con = [buffer] и buffer = conPeek(con,1). Соответственно, сэкономить время на переделку кода. Старый способ упаковки имеет еще преимущество при отладке, так как в отладчике видно содержимое контейнера и можно посмотреть все поля буфера. А новый способ покажет обычный blob по которому ничего непонятно. Последний раз редактировалось Logger; 16.02.2017 в 18:17. |
|
|
За это сообщение автора поблагодарили: raz (10), Raven Melancholic (5), -DocSerzh- (1), _scorp_ (5). |