15.06.2006, 20:40 | #11 |
Moderator
|
Замерил способ "через SysExcel":
X++: static void SpeedTest_Job3_SysExcel(Args _args) { LedgerTrans ledgerTrans; LedgerTable ledgerTable; int row; int timeFullStart, timeFullFinish, timeFullTotal; SysExcelCells cells; COM rng, xlApp; ; timeFullStart = timenow(); // обратите внимание, что если нам нужны, например, только ячейки рабочего листа 1, // то нет необходимости выделять отдельные переменные для всех вышестоящих объектов // можно всё указать в одной строке через точки - почти как в VBA :) cells = SysExcelApplication::construct().workbooks().add().worksheets().itemFromNum(1).cells(); // но нам потребуется объект Application - хотя бы для того, чтобы сделать Excel видимым // в рамках примера получим его как "COM от COM-а" любой ячейки, например, А1 rng = cells.range('A1').comObject(); // Range xlApp = rng.Application(); // Excel.Application xlApp.Visible(true); // в эсперименте на скорость - комментировался/раскомментировался этот оператор // повторяю - этот "изврат" выше сделан для целей примера // без использования COM-переменных можно было бы последовательно оформить вот так: // SysExcelApplication xlApp; // SysExcelCells cells; // ................................ // xlApp = SysExcelApplication::construct(); // cells = xlApp.workbooks().add().worksheets().itemFromNum(1).cells(); // и дальше спокойно распоряжаться этими двумя переменными // для работы с ячейками первого рабочего листа новой рабочей книги row = 0; while select ledgerTrans join ledgerTable where ledgerTrans.AccountNum == ledgerTable.AccountNum { row++; if (row > 50000) break; cells.item( row, 1).value( ledgerTrans.RecId ); cells.item( row, 2).value( ledgerTrans.AccountNum ); cells.item( row, 3).value( ledgerTable.AccountName ); cells.item( row, 4).value( strfmt('%1', ledgerTable.AccountPlType) ); cells.item( row, 5).value( ledgerTrans.BondBatchTrans_RU ); cells.item( row, 6).value( ledgerTrans.BondBatch_RU ); cells.item( row, 7).value( ledgerTrans.TransDate ); cells.item( row, 8).value( ledgerTrans.Txt ); cells.item( row, 9).value( ledgerTrans.AmountMST ); cells.item( row, 10).value( strfmt('%1', ledgerTrans.Crediting) ); } xlApp.visible(true); timeFullFinish = timenow(); timeFullTotal = timeFullFinish - timeFullStart; info('Время выполнения, сек'); info(int2str(timeFullTotal)); } 1. 1228 сек - т.е. чуть больше 20 минут - когда сразу делаем видимым окно Excel в начале процедуры (см. в коде "xlApp.Visible(true); // в эсперименте на скорость...") 2. 1060 сек - т.е. чуть меньше 18 минут - когда показываем Excel только в конце (см. в коде "// xlApp.Visible(true); // в эсперименте на скорость...") Делать Visible(true) в начале - плохая практика, AndyD абсолютно прав! Но в рамках эксперимента, конечно, можно посмотреть и так, и сяк С джобами SpeedTest_Job1 и SpeedTest_Job2 имеет смысл сравнивать только первый результат, поскольку и они тоже прогонялись при начальном Visible(true). Результат "1228 сек" несколько больше, чем у _Job2 (1090 сек), и это объяснимо: представители семейства системных классов SysExcel оформлены как "обертки" над COM и, соответственно, часть времени тратится на "продирание" через эти "обертки", в то время, как _Job2 фактически использует чистый COM. Результат "1228 сек" ниже "1060 сек" примерно на (1228-1060)/1228 = около 14 % - что я и обещал: Цитата:
Сообщение от Gustav
Да, разница в скорости порядка 10-15 процентов.
Мне он, однако, понравился другим, в частности: - возможностью писать "почти как на VBA c многими точками" (см. комментарии в тексте джоба), - писать нормально Value, а не Value2 (при этом класс SysExcelCell сам берет на себя ответственность за обработку value - "до XP или после" ). |
|
Теги |
benchmark, download, excel, faq, xml, законченный пример, производительность, экспорт/импорт |
|
|