В марте этого года я протестировал скорость чтение информации из файла MS Excel библиотеками работающие с файлом MS Excel "напрямую" (Чтение из MS Excel. Кто быстрее?). Сегодня давайте взглянем, как эти библиотеки справляются с записью файла.
Мой тест создает новый XLSX-файл с одним листом, на который записывает 10000 строк по 100 столбцов.
Каждая библиотека формирует файл 10 раз и результатом теста является среднее время. В качестве компилятора использована RadStudio v10.3.2. А результаты подтверждены на другом компьютере с компиляцией в RadStudio v10.3.1.const ciRowCount = 10000; ciColCount = 100;
Тест №1. Начнем с лидера по скорости чтения – с Axolot XLSReadWrite
Результатыprocedure WriteXlsRW; var XLS: TXLSReadWriteII5; j, iRow, iCol, iRowCount, iColCount: Integer; t: TStopwatch; begin iRowCount := ciRowCount - 1; iColCount := ciColCount - 1; Write('1. XLSReadWrite: '); t := t.StartNew; for j := 1 to 10 do begin xls := TXLSReadWriteII5.Create(nil); try for iRow := 0 to iRowCount do for iCol := 0 to iColCount do xls[0].AsInteger[iCol, iRow] := iCol+iRow; xls.SaveToFile('XLrw.xlsx'); finally xls.Free; end; end; t.Stop; WriteLn(t.ElapsedMilliseconds div 10); end;
32-бит: 1323 мс
64-бит: 1595 мс
Тест №2. Оказалось, что по аналогии с "DirectRead mode" для чтения у Axolot XLSReadWrite есть "DirectWrite mode" для записи
Результатыtype TOnWriteCell = class(TObject) procedure XLSWriteCell(ACell: TXLSEventCell); end; procedure TOnWriteCell.XLSWriteCell(ACell: TXLSEventCell); begin ACell.AsFloat := ACell.Col + ACell.Row; end; procedure WriteXlsRWd; var xls: TXLSReadWriteII5; wc: TOnWriteCell; t: TStopwatch; j: Integer; begin Write('2. XLSReadWrite Direct: '); t := t.StartNew; for j := 1 to 10 do begin wc := nil; xls := TXLSReadWriteII5.Create(nil); try xls.SetDirectWriteArea(0, 0, 0, ciColCount - 1, ciRowCount - 1); xls.Filename := 'XLrwD.xlsx'; xls.DirectWrite := True; wc := TOnWriteCell.Create; xls.OnWriteCell := wc.XLSWriteCell; xls.Write; finally xls.Free; wc.Free; end; end; t.Stop; WriteLn(t.ElapsedMilliseconds div 10); end;
32-бит: 1170 мсДля 32-х бит прирост скорости в 153 мс. Это почти 12%!
64-бит: 1482 мс
Тест №3. Перейдем к TMS FlexCel
Результатыprocedure WriteFlexCel; var xls: TXlsFile; j, iRow, iCol: Integer; t: TStopwatch; begin Write('3. FlexCel: '); t := t.StartNew; for j := 1 to 10 do begin xls := TXlsFile.Create(True); xls.NewFile(1); try for iRow := 1 to ciRowCount do for iCol := 1 to ciColCount do xls.SetCellValue(iRow, iCol, iCol+iRow); xls.Save('FlexCell.xlsx'); finally xls.Free; end; end; t.Stop; WriteLn(t.ElapsedMilliseconds div 10); end;
32-бит: 1502 мс32-х битная версия экспорта TMS FlexCel на 179 мс медленнее, чем XLSReadWrite. И на 332 мс медленнее XLSReadWrite в "DirectWrite mode"! Для меня это не совсем ожидаемый и приятный результат. Для тех, кто не читал заметку о тестировании импорта скажу: я много лет использовал XLSReadWrite, а лет 7-9 тому назад перешел на FlexCel.
64-бит: 1468 мс
Тест №4. Для полноты картины глянем на новичка в области экспорта данных в формат в MS Excel – на TXlsMemFileEh из EhLib
Результатыprocedure WriteEh; var xls: TXlsMemFileEh; Sheet: TXlsWorksheetEh; j, iRow, iCol, iRowCount, iColCount: Integer; t: TStopwatch; begin iRowCount := ciRowCount - 1; iColCount := ciColCount - 1; Write('4. EhLib: '); t := t.StartNew; for j := 1 to 10 do begin xls := TXlsMemFileEh.Create; Sheet := xls.Workbook.Worksheets[0]; try for iRow := 0 to iRowCount do for iCol := 0 to iColCount do Sheet.Cells[iCol, iRow].Value := iCol+iRow; xls.SaveToFile('EhLib.xlsx'); finally xls.Free; end; end; t.Stop; WriteLn(t.ElapsedMilliseconds div 10); end;
32-бит: 16063 мсПроигрыш конкурентам по тесту больше чем в 10 раз! Так как EhLib – это не библиотека для работы с файлами MS Excel, то я понимал, что результат может быть печальным, но не думал, что настолько. Добавим к этому то, что файл от 32-х битной версии экспорта был сформирован не полностью и при его открытии MS Excel спросил: "Ошибка в части содержимого в книге EhLib.xlsx. Выполнить попытку восстановления?". Попытка восстановить закончилась неудачей: "Замененный компонент: часть /xl/worksheets/sheet1.xml с ошибкой XML. Непредусмотренный конец входных данных. Строка 2, столбец 10605714". При этом файл созданный 64-х битной версией экспорта открылся нормально. Это фиаско братан!
64-бит: 16271 мс
Итак, подведем итоги
Библиотека | 32-бит | % от лучшего результата | 64-бит | % от лучшего результата | средний % |
Axolot XLSReadWrite | 1323 | 113.08 | 1595 | 108.65 | 110.87 |
Axolot XLSReadWrite "DirectWrite mode" | 1170 | 100.00 | 1482 | 100.95 | 100.48 |
TMS FlexCel | 1502 | 128.38 | 1468 | 100.00 | 114.19 |
EhLib | 16063 | 1372.91 | 16271 | 1108.38 | 1240.65 |
Выводы
1. Axolot XLSReadWrite является не только лидером по скорости чтении информации из файла MS Excel, но и по скорости записи в файл. Похоже на то, что для увеличения скорости работы утилит импорта/экспорта мне надо переходить обратно на XLSReadWrite...
2. TXlsMemFileEh из EhLib пока нельзя рассматривать как альтернативу библиотекам XLSReadWrite и FlexCel. Но я думаю, что он вполне подойдет для выгрузки нескольких десятков или сотен строк.
P.S. Использованы последние доступные на данный момент версии библиотек: Axolot XLSReadWrite v6.00.57, TMS FlexCel v7.0 и EhLib v9.4.015.
У меня есть опыт работы и с лицензионными XlsReadWrite и с FlexCel. Я остановилась на FlexCel, т.к. ощутила разницу в подходе к саппорту от авторов этих библиотек. Скорость отклика и готовность помочь - как небо и земля. Автор FlexCel всегда дает ответы и советы в течение нескольких часов или даже минут. А автор XLSReadWrite на форуме поддержки очень высокомерен.
ОтветитьУдалитьСкорость не главное. Главное - функциональные возможности. У flexcel они богаче и реализованы удобнее.
ОтветитьУдалитьСогласен, что скорость не главное. Но иногда скорость имеет значение. Например, у меня есть консольные утилиты, которыми пользователи конвертируют данные из одного формата или системы в другой формат или систему. Попутно с этими данными проводят различные манипуляции. Количество строк в этих файлах исчисляется сотнями тысяч строк (иногда и под миллион). В результате там несколько миллисекунд, там несколько секунд... На большом количестве файлов это заметное время.
ОтветитьУдалить