使用 StreamWriter 保存工作簿时,内存使用量很高
说明
StreamWriter'将每16 MB将工作表 XML 溢出到临时文件中,使内存使用保持平平。 然而,当工作手册被保存起来时,这种好处就丧失了:拯救'、拯救As'和写'通过File.WriteTo'的所有路线,该路线称为WriteToBuffer'并用`字节'组装了**全行压缩拉链档案。 在给目的地写字节之前缓冲。 因此,峰值内存会以输出文件大小(加上"字节")来缩放. 缓冲"增长翻倍",这辜负了流线作家为大型活页书(100万行以上)的目的.
两个小的相关问题 在同一路径:
- " WriteToZip " 将 " io " 的 " stream " 临时档案复制入档案。 Copy's默认的 32 KB 缓冲器;在一个 1M- row 文件上,这些小的“ pread” syscalls 占了配置图中CPU总时间的~46%.
- " tempFiles " 循环使用 " readBytes " ,将每个磁盘上的部分全部装入内存并储存入 " f " 。 Pkg ' 永远。
- 复制问题的步骤
- 将1 000 000行(每行10个单元格)写入 " NewStreamWriter " / " SetRow " / " Flush " ——记忆保持平整(~22 MB堆),如所预期。
- 呼叫 " 拯救 " ,在保存时观察峰值记忆。
开始 主软件包
导入( E) "fmt" (英语). "运行时间" "钢筋"
"GitHub.com/xuri/excelize/v2" (中文(简体) ). (中文(简体) ).
func heapMB () uint64 { Var m跑步时间. 示意图 运行时间. GC () 运行时间。 读取MemStats( & m) 返回 m.HeapAlloc >> 20 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
func 主 () { f: = 卓越. NewFile( ) 推迟 f. 关闭( ) sw, 错误 := f. NewStreamWriter ("Sheet1") 如果错误 ! = 无 { fmt. (英语). 打印( err) 返回时 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 行 := make([] interface * *, 10) r := 1;r = 1000000;r++ { c:=0;c < 10;c++ { 如果 c% 2 == 0 { 页:1 否则 行 [c] = "值-" + strconv.Itoa(r+c) {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 单元格, : = excellization. 坐标ToCellName (1, r) 如果错误 := sw.SetRow(单元格,行); 错误 != 0 { fmt. (英语). 打印( err) 返回时 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 如果错误 : = sw. Flush (); 错误 ! = 0 { fmt. (英语). 打印( err) 返回时 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? fmt. (英语). Println ("写后堆放:", heapMB (), "MB") //~22 MB, 流出作品 如果错误 := f.saveAs ("Book1. xlsx"); 错误 != 0 { fmt. (英语). 打印( err) 返回时 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? fmt. (英语). Println ("保存后堆积:", heapMB (), "MB") / 内存按文件大小缩放 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
描述你得到的结果
保存期间的峰值内存随输出文件大小而线性地增长(峰值内存每10ms就用背景goroutine读取'runtime'来取出样本). MemStats; 1 048 576个工作表限制上行分多个工作表:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|.
|
. . . . . . .内容来源: qax-os/excelize