PHPExcel与PhpSpreadsheet内存占用对比及使用缓存的影响

话不多说先上结果对比图(数据怎么来的往下拉看代码)


image.png

注:

  • 数据有7列(1列为空,1列约25中文,其他列简单int),生成xlsx文件大小 2,699K
  • PhpSpreadsheet使用Memcached和Redis性能表现差不多。
  • 【save输出】的峰值占用计算是在【save输出】完成时内存峰值大于【save输出】前内存峰值的情况下:
    操作占用峰值 = 操作完成后峰值 - 操作前内存用量
    未突破之前峰值时不计算
  • PHPmemory_limit限制的是emalloc()分配的内存,即memory_get_peak_usage()不传true获取到的峰值内存用量(黄)。
  • 之所以要记录多次峰值内存是具体步骤的高占用内存可能在执行完成时被回收了。
  • PhpSpreadsheet缓存使用参阅:http://phpspreadsheet.readthedocs.io/en/develop/topics/memory_saving/

结论

  • 通过测试得出的各区间的峰值内存用量来看,save()保存输出的过程中是最消耗内存的。
  • EXCEL文档是基于xml的zip打包格式,改后缀为zip有惊喜,并非直接文本文件,每次修改都需要整体读入再覆写。数据行列过多建议使用文本拼接生成csv文件。
  • 几乎可以放弃使用外部缓存来解决内存溢出的想法
    下图为单次10W*7列使用Redis的操作记录,有420W次的Redis操作,Redis服务器在操作期内网络流入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 .= '╔结果数组:'.(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数组:'.(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
╔结果数组:54.641174316406MB
╠此前峰值内存:104.72563934326MB
╚time(s):1522826207
╔单元格完成:198.46007537842MB
╠此前峰值内存:198.46117401123MB
╚↑time(s):1522826216
╔unset数组: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
╔结果数组:54.532043457031MB
╠此前峰值内存:104.61650848389MB
╚time(s):1522825234
╔new SS:56.107322692871MB
╠此前峰值内存:104.61650848389MB
╚↑time(s):1522825234
╔单元格完成:269.50070953369MB
╠此前峰值内存:269.5018081665MB
╚↑time(s):1522825244
╔unset数组: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
╔结果数组:54.658271789551MB
╠此前峰值内存:104.74273681641MB
╚time(s):1522826626
╔new SS:56.377334594727MB
╠此前峰值内存:104.74273681641MB
╚↑time(s):1522826626
╔单元格完成:100.63970184326MB
╠此前峰值内存:110.61833953857MB
╚↑time(s):1522826912
╔unset数组:46.510581970215MB
╚time(s):1522826912
╔createWriter:47.347480773926MB
╠此前峰值内存:110.61833953857MB
╚time(s):1522826912
╔over:67.271064758301MB
╚time(s):1522828298
脚本内存峰值:315.16254425049MB
物理峰值:410MB
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容

  • 转载地址:http://gnucto.blog.51cto.com/3391516/998509 Redis与Me...
    Ddaidai阅读 21,446评论 0 82
  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,964评论 2 27
  • Redis的内存优化 声明:本文内容来自《Redis开发与运维》一书第八章,如转载请声明。 Redis所有的数据都...
    meng_philip123阅读 18,885评论 2 29
  • “平凡的世界,不平凡的人生” 刚开始翻开这本书,一点点也看不下去,就感觉和我的世界好遥远好遥远,但当我认认真真地翻...
    i清沐阅读 298评论 0 0
  • 文/北有昔年 01. 劳累了一天,当我拖着疲惫的身体回到出租屋时,看到等待在门口的两人,我突然好像忘记了劳累,撒开...
    北有昔年阅读 3,518评论 37 51