PHPExcel與PhpSpreadsheet內存占用對比及使用緩存的影響

話不多說先上結果對比圖(數(shù)據(jù)怎么來的往下拉看代碼)


image.png

注:

  • 數(shù)據(jù)有7列(1列為空,1列約25中文,其他列簡單int),生成xlsx文件大小 2,699K
  • PhpSpreadsheet使用Memcached和Redis性能表現(xiàn)差不多。
  • 【save輸出】的峰值占用計算是在【save輸出】完成時內存峰值大于【save輸出】前內存峰值的情況下:
    操作占用峰值 = 操作完成后峰值 - 操作前內存用量
    未突破之前峰值時不計算
  • PHPmemory_limit限制的是emalloc()分配的內存,即memory_get_peak_usage()不傳true獲取到的峰值內存用量(黃)。
  • 之所以要記錄多次峰值內存是具體步驟的高占用內存可能在執(zhí)行完成時被回收了。
  • PhpSpreadsheet緩存使用參閱:http://phpspreadsheet.readthedocs.io/en/develop/topics/memory_saving/

結論

  • 通過測試得出的各區(qū)間的峰值內存用量來看,save()保存輸出的過程中是最消耗內存的。
  • EXCEL文檔是基于xml的zip打包格式,改后綴為zip有驚喜,并非直接文本文件,每次修改都需要整體讀入再覆寫。數(shù)據(jù)行列過多建議使用文本拼接生成csv文件。
  • 幾乎可以放棄使用外部緩存來解決內存溢出的想法
    下圖為單次10W*7列使用Redis的操作記錄,有420W次的Redis操作,Redis服務器在操作期內網(wǎng)絡流入1G、流出1.3G,可見開銷非常之高。然而效果卻并不如人意。


    image.png

以下測試代碼的示例

<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;

$str = 'startTime(s):'.time()."\r\n";
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
$str .= '╔new PDO:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╚time(s):'.time()."\r\n";
$res = $pdo->query('SELECT * from excel_test LIMIT 100000');
$res = $res->fetchAll(PDO::FETCH_ASSOC);
$str .= '╔結果數(shù)組:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╠此前峰值內存:'.(memory_get_peak_usage()/1024/1024)."MB\r\n";
$str .= '╚time(s):'.time()."\r\n";

$spreadsheet = new Spreadsheet();
$str .= '╔new SS:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╠此前峰值內存:'.(memory_get_peak_usage()/1024/1024)."MB\r\n";
$str .= '╚↑time(s):'.time()."\r\n";
$spreadsheet->setActiveSheetIndex(0);
$spreadsheet->getActiveSheet()->setTitle('test');
$azs = range('A','Z');
$titles = array_keys($res[0]);
foreach ($titles as $k => $title) {
    $spreadsheet->getActiveSheet()->setCellValue(($azs[$k]).'1', $title);
}
foreach ($res as $i => $row){
    $m = 0;
    foreach ($row as $val) {
        $spreadsheet->getActiveSheet()->setCellValue(($azs[$m]).($i+2), $val);
        ++$m;
    }
}
$str .= '╔單元格完成:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╠此前峰值內存:'.(memory_get_peak_usage()/1024/1024)."MB\r\n";
$str .= '╚↑time(s):'.time()."\r\n";
unset($res);
$str .= '╔unset數(shù)組:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╚time(s):'.time()."\r\n";
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setPreCalculateFormulas(false);
$str .= '╔createWriter:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╠此前峰值內存:'.(memory_get_peak_usage()/1024/1024)."MB\r\n";
$str .= '╚time(s):'.time()."\r\n";

$writer->save('./wmtest.xlsx');
$str .= '╔over:'.(memory_get_usage()/1024/1024)."MB\r\n";
$str .= '╚time(s):'.time()."\r\n";
$str .= '腳本內存峰值:'.(memory_get_peak_usage()/1024/1024)."MB\r\n";
$str .= '物理峰值:'.(memory_get_peak_usage(true)/1024/1024)."MB\r\n";
file_put_contents("./wmtest.txt",$str);

PHPExcel 測試結果

startTime(s):1522826206
╔結果數(shù)組:54.641174316406MB
╠此前峰值內存:104.72563934326MB
╚time(s):1522826207
╔單元格完成:198.46007537842MB
╠此前峰值內存:198.46117401123MB
╚↑time(s):1522826216
╔unset數(shù)組:144.33098602295MB
╚time(s):1522826216
╔createWriter:145.26038360596MB
╠此前峰值內存:198.46117401123MB
╚time(s):1522826216
╔over:164.63647460938MB
╚time(s):1522826272
腳本內存峰值:413.024269104MB
物理峰值:500MB

PhpSpreadsheet 測試結果

startTime(s):1522825234
╔new PDO:0.40194702148438MB
╚time(s):1522825234
╔結果數(shù)組:54.532043457031MB
╠此前峰值內存:104.61650848389MB
╚time(s):1522825234
╔new SS:56.107322692871MB
╠此前峰值內存:104.61650848389MB
╚↑time(s):1522825234
╔單元格完成:269.50070953369MB
╠此前峰值內存:269.5018081665MB
╚↑time(s):1522825244
╔unset數(shù)組:215.37158966064MB
╚time(s):1522825245
╔createWriter:216.2133102417MB
╠此前峰值內存:269.5018081665MB
╚time(s):1522825245
╔over:235.63749694824MB
╚time(s):1522825306
腳本內存峰值:483.96257019043MB
物理峰值:512MB

PhpSpreadsheet 使用Redis緩存測試結果

╔new PDO:0.52817535400391MB
╚time(s):1522826626
╔結果數(shù)組:54.658271789551MB
╠此前峰值內存:104.74273681641MB
╚time(s):1522826626
╔new SS:56.377334594727MB
╠此前峰值內存:104.74273681641MB
╚↑time(s):1522826626
╔單元格完成:100.63970184326MB
╠此前峰值內存:110.61833953857MB
╚↑time(s):1522826912
╔unset數(shù)組:46.510581970215MB
╚time(s):1522826912
╔createWriter:47.347480773926MB
╠此前峰值內存:110.61833953857MB
╚time(s):1522826912
╔over:67.271064758301MB
╚time(s):1522828298
腳本內存峰值:315.16254425049MB
物理峰值:410MB
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 轉載地址:http://gnucto.blog.51cto.com/3391516/998509 Redis與Me...
    Ddaidai閱讀 21,548評論 0 82
  • NOSQL類型簡介鍵值對:會使用到一個哈希表,表中有一個特定的鍵和一個指針指向特定的數(shù)據(jù),如redis,volde...
    MicoCube閱讀 4,160評論 2 27
  • Redis的內存優(yōu)化 聲明:本文內容來自《Redis開發(fā)與運維》一書第八章,如轉載請聲明。 Redis所有的數(shù)據(jù)都...
    meng_philip123閱讀 19,071評論 2 29
  • “平凡的世界,不平凡的人生” 剛開始翻開這本書,一點點也看不下去,就感覺和我的世界好遙遠好遙遠,但當我認認真真地翻...
    i清沐閱讀 325評論 0 0
  • 文/北有昔年 01. 勞累了一天,當我拖著疲憊的身體回到出租屋時,看到等待在門口的兩人,我突然好像忘記了勞累,撒開...
    北有昔年閱讀 3,590評論 37 51

友情鏈接更多精彩內容