Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/250.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 盒/嘴-使用十六进制颜色与预定义颜色时占用大量内存_Php_Phpexcel_Spout - Fatal编程技术网

Php 盒/嘴-使用十六进制颜色与预定义颜色时占用大量内存

Php 盒/嘴-使用十六进制颜色与预定义颜色时占用大量内存,php,phpexcel,spout,Php,Phpexcel,Spout,我正在使用这个库,与使用诸如color::blue之类的预定义颜色相比,将StyleBuilder与自定义十六进制颜色(例如,0000FF表示蓝色)一起使用似乎占用了大量内存。为什么会这样 相关片段: //LOW MEMORY $row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor(Color::BLUE)->build()); //HIGH MEMORY $row[]

我正在使用这个库,与使用诸如color::blue之类的预定义颜色相比,将StyleBuilder与自定义十六进制颜色(例如,0000FF表示蓝色)一起使用似乎占用了大量内存。为什么会这样

相关片段:

//LOW MEMORY
$row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor(Color::BLUE)->build());

//HIGH MEMORY
$row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor($colorHex)->build());
输出:

//LOW MEMORY
$row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor(Color::BLUE)->build());

//HIGH MEMORY
$row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor($colorHex)->build());
setFontColor(颜色:蓝色):
峰值内存使用量:1666 KB

setFontColor($colorHex):
峰值内存使用量:189436KB

完整代码:

//LOW MEMORY
$row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor(Color::BLUE)->build());

//HIGH MEMORY
$row[] = WriterEntityFactory::createCell('test', (new StyleBuilder())->setFontColor($colorHex)->build());
(出于演示目的,我正在加载一个小的250x150图像以提供多个颜色值)

tl;博士
虽然可以改进
喷口
,但这并不是库的真正缺陷(您可能希望)

故事 好吧,这里有一些事情在起作用。。我用来测试的代码在我文章的底部-关键的相关颜色函数是
jonEg
jonEgQuant
(这是一个内部可以调整的
$by
变量)

  • Excel中的样式有点像HTML+CSS。样式最初在文件(在标题块中)中定义,然后在图纸中由名称(类)引用。从根本上说,这表明Excel存储格式不是为过多的样式设计的,而是为在许多单元格上重复使用的少数样式设计的

  • spoot
    向用户隐藏样式定义的复杂性-如果已经定义了样式(即已经存在确切的样式),则它将重用该定义,否则将定义新样式

  • spoot
    按样式对象构建所有样式的索引,并将其存储在数组中。每个样式大约1749字节,此索引占用内存(除了它在内存中用于生成文件的实际样式对象)这可以在
    Spout

  • 有了这段代码,我保证每个单元格都有不同的样式(使用行/列位置来定义颜色的红色和绿色分量)-这比图像颜色拾取更极端,但可能不会太多(如果没有示例图像,我无法判断)。RGB三元组提供16M颜色。。但是我们的眼睛不能总是检测到几点的差异。例如,在红色渐变中,255254253…128看起来很平滑,但随机分布的255254253的单个块可能看起来像单一颜色。对于除原色以外的任何颜色,这种差异现在适用于三维(r、g和b)。该方法利用了这一点(压缩和重建过程中的噪声的组合),因此颜色拾取看起来像一个统一的块,每次仍然会返回稍有不同的值

  • 当您使用
    jonEg
    运行我的代码时,您会得到(100*150+1)15001个样式,仅
    Spout
    中的索引就需要(15001*1749/1024/1024)~25MB的内存。同样,需要使用此索引来防止Excel中的每个单元格都有自己的样式(当然,在这个精心设计的示例中,我已经确保它毫无意义-每个单元格都有自己的样式)-这使用了~100MB的内存

  • 当您使用
    jonEgQuant
    (保留
    $by=16;
    )运行我的代码时,只需要71种样式(但这是非常极端的舍入,总共只允许4096种颜色),这使用了~2MB的内存

  • 当您设置
    $by=4
    (在
    ColorBuilder::jonEgQuant
    )时-您现在拥有多达25万种颜色,需要989种样式,使用~7MB内存(更重要的是,在Excel中打开时,这看起来类似于
    jonEg

  • spoot
    包括一种将RGB十进制值转换为字符串的方法
    Color::RGB($r,$g,$b)
    ——但这不会改变结果(
    spootdoc
    方法)

  • 一种样式的尺寸比这多得多——我用过背景色,但有前景(你的例子)、下划线、粗体、斜体、字体、字体大小——所有这些都会成倍增加样式的数量(减少这里的颜色空间可以解决你的问题,但可以通过改变其他样式组件来撤销)

外卖
  • 问题不在于使用十六进制代码、RGB值或常量,而在于使用的样式数量

  • 减少使用的样式数量-Excel不需要大量使用,
    spoot
    同样也没有为此进行优化。压缩颜色(通过使用
    jonEgQuant
    对值进行舍入)是一种方法

  • 改进
    spoot
    样式索引机制,但请注意,索引只消耗了部分内存-它不小,但不是唯一的贡献者-每个样式对象都需要生成结果。删除这种样式的缓存(对于这个人为的示例没有帮助)将内存使用率提高到40MB(并生成相同的Excel文件)。60%的节省不是什么,但是更多的样式可以提高内存使用率、更大的Excel文件以及更慢地打开/呈现这些文件

测试笔记
  • 我在测试时放弃了图像读取/颜色采集,因为它可能会增加内存使用,但不会增加问题的实质

  • $colCount=250
    (来自您的示例)您超过了PHP中128MB的默认内存限制,最好将其设置为
    $colCount=100
    并且您可以运行所有测试,而无需更改该设置

  • 我切换到设置背景色,在Excel中打开时更容易看到差异

  • 对于每个颜色生成器(
    jonEg
    spoutDoc
    fixedEg
    jonEgQuant
    ),将生成不同的XLSX(有助于查看文件大小和渲染差异)

  • 文件大小与Excel的复杂性相匹配-
    jonEg
    是一个179KB的文件(Excel很难