这个问题是关于使用 gm4java 库与 Graphics Magick 交互(在 scala 中)。
我一直在测试 PooledGMService,正如它所演示的那样 here使用 scala,并且运行良好。
但是,我注意到它的执行方式与 gm 命令行界面中的批处理模式不同(gm batch batchfile.gm
)。当我从命令行运行包含任意数量图像的 gm 批处理文件时,它会启动 1 个 gm 进程。但是,如果我:
val config = new GMConnectionPoolConfig()
val service = new PooledGMService(config)
然后跨 4 个线程共享服务实例,其中我对每个线程的一个图像执行一些操作,例如:
service.execute(
"convert",
srcPath.toString(),
"-resize", percent + "%",
outPath.toString()
)
我看到创建了 4 个单独的 gm 进程。
我相信这会对性能产生影响(使用 100 个图像进行测试,使用上面提到的针对带有批处理文件的 gm cli 的代码,需要相同的时间,但我的 scala 代码使用 4 倍的 CPU)。
我的问题是:如何使用 gm4java 以便单个 gm 进程可以处理多个图像(或至少对同一图像进行多种转换),就像 cli 批处理模式一样?我已经尝试了一些尝试(有些非常愚蠢) no luck here .
我的确切scala代码可以是found here if you are curious .
更新 2014 年 5 月 27 日
在 comment by gm4java's author 的指导下我意识到我正在对两个不同的 gm 命令进行基准测试。更新后的基准测试结果为:
100 x 30MB images (3.09GB tot)
on i7 quadcore (8 logical cpu's w/ hyper-threading)
Criteria Time
gm cli batchfile 106s
my code 1 thread 112s
my code 4 threads 40s
my code 6 threads 31s
my code 7 threads 31s
my code 8 threads 28s
经过仔细检查,我还发现,当我的代码运行时,具有相同进程 ID 的相同 gm 进程始终保持运行。这减轻了我的担忧,即由于与启动和终止 gm 线程相关的一些开销而导致性能下降。
改写
我想我的问题的核心是如何使 gm4java 尽可能快? tip about matching gm the threadcount with the machine's execution engine count很有用。还有什么想到的吗?
我的特定用例是将输入图像的大小(平均为 30MB,偶尔为 50-60MB,很少为 100-500MB)调整为几个设定大小(缩略图是最重要和最高优先级的)。部署可能会在 amazon ec2具有 7 或 14 个“计算单元”
最佳答案
PooledGMService的设计是通过启动多个 GM 进程实例以高度并发的方式处理您的图像处理请求,从而最大限度地利用您的计算机能力。 100 个图像的样本量太小,无法测试性能。如果您的目标是充分利用多 CPU 服务器来转换图像,则需要使用大量样本(至少数千个)进行测试并调整配置以找到要使用的最佳并发 GM 进程数。请参阅 GMConnectionPoolConfig 的文档对于所有配置选项。
如果您只有 8 个 CPU,请不要启动超过 7 个 GM 进程。如果您在 2-CPU 笔记本电脑上进行测试,请勿运行超过 2 个 GM 进程。在示例中,您接受了所有默认配置设置,这将根据需要启动最多 8 个 GM 进程。但对于在仅有 2 个 CPU 的笔记本电脑上处理 100 个图像而言,这种配置并不合适。
如果您只想模仿命令行批处理模式。比SimpleGMService是你最好的 friend 。看使用模式here .
正确的解决方案很大程度上取决于您的实际用例。如果您能告诉我们更多关于您想要实现的目标、您的硬件环境等信息,我们可以更好地为您提供帮助。
关于java - 使用 gm4java 在单个进程中进行多个图像操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23846193/