如何加速GhostScript?

37

我有一个大约50MB的100页PDF文档。我正在使用下面的脚本处理它,每一页需要大约23秒的时间。这个PDF是一个纸质文件的扫描件。

gswin32.exe -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.3 
            -dPDFSETTINGS=/screen -sOutputFile=out4.pdf 09.pdf
有没有什么我可以做来加快这个过程?我已经确定-dPDFSettings=/screen是导致它如此缓慢的原因,但是如果不使用它,我得不到良好的压缩效果...
更新: 好的,我尝试将其更新为下面的内容。我是否正确地使用了-c 30000000 setvmthreshold部分?
gswin32.exe -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.3 
            -dPDFSETTINGS=/screen -dNumRenderingThreads=2 -sOutputFile=out7.pdf 
            -c 30000000 setvmthreshold -f 09.pdf

压缩需要时间,请确保在开始之前将图像尽可能地减小。 - Orbling
很不幸,我正在尝试解决的问题是我们数据库中已经有大约 600GB 的超大图片。我本来希望能够使用 Ghostscript 来减小图片大小,但看起来它可能在完成之前我就退休了。 - Abe Miessler
OCR之后,图像就会减少,光栅化的内容也会减少,所有操作都会更快 :-) - user502515
5个回答

39

如果您使用的是多核系统,请使用以下代码来利用多个CPU核心:

-dNumRenderingThreads=<number of cpus>

让它使用最多30MB的内存:

-c "30000000 setvmthreshold"

尝试禁用垃圾回收器:

-dNOGC

详细信息请参见Ghoscript文档中的Improving Performance部分。


谢谢你的信息,@Ismail。我更新了我的问题,包括我添加的内容以利用RAM和CPU核心。你能看一下RAM部分,看看它是否正确吗? - Abe Miessler
看起来-c参数需要双引号,还添加了垃圾收集器提示,请尝试给它更多的RAM并查看是否有帮助。 - ismail
3
当我尝试在我的脚本中包含"-c“30000000 setvmthreshold”变量的不同版本时,我总是会得到“无法打开初始设备,退出。”错误。为什么?如何避免这个错误?是否需要sudo权限? - nutty about natty
5
我认为你需要将其放在输入文件名之前,并加上“-f”,就像这样:gs ... -c "30000000 setvmthreshold" -f input_file.pdf - Olivier 'Ölbaum' Scherler
1
请注意,此讨论涉及生成位图格式输出的设备。这些参数对于矢量设备(如pdfwrite)没有影响。 - SOUser

14

我在一台核心为i7的电脑上处理了一个大约300页的PDF文件,并发现添加以下选项可以显著提高速度:

                            %-> comments to the right 
-dNumRenderingThreads=8     % increasing up to 64 didn't make much difference
-dBandHeight=100            % didn't matter much
-dBandBufferSpace=500000000 % (500MB)
-sBandListStorage=memory    % may or may not need to be set when gs is compiled
-dBufferSpace=1000000000    % (1GB)

对我来说,-c 1000000000 setnvmthreshold -f 这个东西没有太大的区别,供参考。


你能透露一下通过这些参数可以提高多少性能吗?你有提高PDF转PS速度的经验吗? - Lukas
1
哇!特别是-dBandBufferSpace=500000000和-dBufferSpace=1000000000,将具有大型位图图形的PDF转换为300 ppi的PNG,从原来的14分钟缓慢转换到仅需50秒,使用-dNumRenderingThreads=4仅需20秒。 - Roman Scher
1
经过进一步测试,我发现在某些情况下同时设置“-dBandBufferSpace”和“-dBufferSpace”实际上是适得其反的,并且会使较大的PDF文档的光栅化过程显著变慢。Ghostscript文档也提出了类似建议:“如果您只想为分带分配更多内存以增加分带大小并提高性能,请使用BufferSpace参数,而不是BandBufferSpace。” - Roman Scher

7
你没有说明你的计算机配备了什么CPU和多少RAM。
你的情况如下:
  • 一个PDF扫描文档,平均每页大小约为500 kB。这意味着每一页基本上是一张图片,使用扫描分辨率(至少200 dpi,甚至可能是600 dpi)。
  • 您正在使用Ghostscript重新处理它,使用-dPDFSETTINGS=/screen。这个设置将做很多事情来使文件大小更小。其中最重要的是:
    1. 重新采样所有(彩色或灰度)图像为72dpi
    2. 将所有颜色转换为sRGB
这两个操作在CPU和/或RAM使用方面都相当“昂贵”。
顺便说一句,你的-dCompatibilityLevel=1.3设置不是必需的;它已经被-dPDFSETTINGS=/screen隐式设置了。
试试这个:
gswin32.exe ^
 -o output.pdf ^
 -sDEVICE=pdfwrite ^
 -dPDFSETTINGS=/screen ^
 -dNumRenderingThreads=2 ^
 -dMaxPatternBitmap=1000000 ^
 -c "60000000 setvmthreshold" ^
 -f input.pdf

此外,如果您使用的是64位系统,请尝试安装最新的32位Ghostscript版本(9.00)。它比64位版本性能更好。

请注意,将600dpi扫描页图像缩小到72dpi通常不会花费我23秒钟,而是少于1秒钟。


我有一颗2.79 GHz的处理器和3.5 GB的内存。我尝试了你的方法,但仍然在20秒左右徘徊。我的文档通常每页750k。你能想到其他我可以尝试的方法吗? - Abe Miessler
即使设置了setvmthreshold,该进程仅使用最大16Mb的内存。我做错了什么吗? - Abe Miessler
@ Abe Miessler:如果该进程最多使用 16 Mb 的内存,这可能意味着对于特定的文件它并不需要更多。为了再次确认设置是否有效,尝试将其值设置为较低的数字,例如 200000。然后再次查看内存使用情况。 - Kurt Pfeifle
@Abe Miessler:你能排除它不是I/O硬盘性能问题导致变慢吗?(我记得以前也遇到过这样的问题-我通过创建一个ramdisk并从/向ramdisk读写文件进行测试,突然性能飙升...) - Kurt Pfeifle
有趣,我以前从未听说过RAMDisk。你能推荐一个好的/免费的吗? - Abe Miessler
显示剩余2条评论

5
为了加速将具有大型位图图形的PDF文件光栅化为高质量的300 ppi PNG图像,我发现将 -dBufferSpace 尽可能设置得高,并将 -dNumRenderingThreads 设置为可用的尽可能多的核心数,对于大多数文件来说最有效,其中 -dBufferSpace 提供的提升最显著。 最好的特定值是:
  • -dBufferSpace=2000000000,即2 GB的缓冲空间。这将一个相对较小的文件的光栅化时间从14分钟缩短到仅50秒。对于较小的文件,将其设置为1 GB没有太大区别,但对于较大的文件,它会产生显着差异(有时快2倍)。尝试将其设置为3 GB或更高,出现启动错误“Unrecoverable error: rangecheck in .putdeviceprops”。

  • -dNumRenderingThreads=8,适用于拥有8个核心的机器。这将同一文件的光栅化时间从14分钟缩短到4分钟(如果使用4个线程,则需要8分钟)。与上面的 -dBufferSpace 选项结合使用,将时间从50秒缩短到25秒。然而,与 -dBufferSpace 结合使用时,增加线程数似乎会产生递减的效果,并且对某些文件几乎没有影响。奇怪的是,对于一些较大的文件,将线程数设置为1实际上比任何其他数字都要快。

整个命令看起来像:
gs -sDEVICE=png16m -r300 -o document.png -dNumRenderingThreads=8 -dBufferSpace=2000000000 -f document.pdf

这是使用Ghostscript 9.52测试的结果,经过测试,参考了@wpgalle3答案中的建议以及Ghostscript文档中的“提高性能”部分。

文档中的一个关键点是,当Ghostscript由于光栅图输出大于-dMaxBitmap的值而使用“分段模式”时,它可以利用多个内核来加速处理。

无效或适得其反的选项:

单独设置-c“2000000000 setvmthreshold”(2 GB)或与-dBufferSpace一起设置似乎没有任何区别。

设置-sBandListStorage=memory导致分段错误。

-dMaxBitmap=2000000000(2 GB)设置后,处理速度显著变慢,并且显然会出现问题,写入数百GB的临时文件而没有停止的迹象,促使我中断了进程。

对于较小的文件,将-dBandBufferSpace设置为-dBufferSpace的一半没有任何效果,但对于较大的文件,实际上使处理速度显著降低了1.5-1.75倍。在Ghostscript文档的“分段参数”部分中,事实上建议不要使用-dBandBufferSpace:“如果您只想为分段分配更多内存,以增加带大小并提高性能,请使用BufferSpace参数,而不是BandBufferSpace。”


1
我可能完全不在适当的位置,但你是否尝试过Djvu文件格式?它通常适用于扫描文档(即使有很多图片),并且它可以提供更好的压缩文件:通常我在黑白科学文章中可以获得两倍的无损大小优势。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接