使用gm4java在单个进程中执行多个映像操作

使用gm4java在单个进程中执行多个映像操作,java,scala,graphicsmagick,Java,Scala,Graphicsmagick,这个问题是关于使用gm4java库与Graphics Magick(在scala中)交互的 我一直在测试PooledGMService,正如它在scala中演示的那样,它工作得很好 但是,我注意到它的执行方式与gm命令行界面中的批处理模式不同(gm batch batchfile.gm)。当我从命令行运行带有任意数量图像的gm批处理文件时,它将启动1个gm进程。但是,如果我: val config = new GMConnectionPoolConfig() val service = new

这个问题是关于使用gm4java库与Graphics Magick(在scala中)交互的

我一直在测试PooledGMService,正如它在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流程

我相信这会对性能产生影响(使用上面提到的代码对带有批处理文件的gm cli进行100个映像的测试需要相同的时间,但我的scala代码使用了4倍的CPU)

我的问题是:如何使用gm4java,使单个gm进程可以处理多个映像(或者至少对同一映像进行几种类型的转换),就像cli批处理模式一样?我试过几次尝试(有些非常愚蠢)

我确切的scala代码,可以是

2014年5月27日更新

在a的指导下,我意识到我正在对两个不同的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尽可能快?这是有用的。我还想到什么了吗

我的特定用例是将输入图像(平均为30MB,偶尔为50-60MB,很少为100-500MB)调整为几个设置大小(缩略图是最重要和最高优先级)。部署可能会使用7或14个“计算单元”

的设计是通过启动多个GM进程实例,以高度并发的方式处理图像处理请求,最大限度地利用您的计算机能力。100图像样本量太小,无法测试性能。如果您的目标是最好地利用多CPU服务器来转换图像,则需要使用大量样本(至少几千个)进行测试,并调整配置,以找到要使用的并发GM进程的最佳数量。有关所有配置选项,请参阅的文档

如果您只有8个CPU,那么启动的GM进程不要超过7个。如果您在一台双CPU笔记本电脑上进行测试,请不要运行超过2个GM进程。在本例中,您接受了所有默认配置设置,这将根据需要启动最多8个GM进程。但在一台只有2个CPU的笔记本电脑上只处理100个图像,这并不是正确的配置

如果您只想模拟命令行批处理模式。比你最好的朋友还要好。看看使用模式


正确的解决方案在很大程度上取决于您的实际用例。如果您能告诉我们更多您想要实现的目标、硬件环境等,我们将为您提供更好的帮助。

感谢您的快速响应!我已经用用例的细节更新了我的问题。如果你有更多关于加速技巧的建议,请告诉我!据我所知,在重新思考了我的应用程序后,PooledGMService仍然最适合我的需要。如果我要实例化几个SimpleGMService连接,我想我会把管理一个进程池的责任推到自己身上,而不是推到您的优化库上!使用“缩放”可以为缩略图提供更好的性能,但对于较大尺寸的图像,图像质量可能不如“转换”好。要使用的GM进程的数量取决于CPU和I/O。从CPU:GM 1:1的比率开始,如果您的I/O很慢,并且您看到CPU没有完全占用,请增加GM进程以充分利用您的CPU。您还需要注意内存使用情况,以避免交换。如果您正在优化吞吐量,还应该禁用GM多线程(选项:-限制线程1)。谢谢,我将很快在生产机器上进行一些测试,使用“限制线程1”选项尝试多个SimpleGMService实例和多个PooledGMService实例,将它们与具有多线程的PooledGMService进行比较。@Ilya,您不需要多个SimpleGMService实例,您可以从同一个SimpleGMService获得多个连接。每个连接可以执行多个GM命令。顺便说一句,我对“限制线程1”的评论应该添加到发送给GM的每个命令中。GM总是使用单线程来处理“缩放”命令。它将使用多线程来处理“convert”命令。这是好的,如果你只使用单一的GM过程。但是,如果您的所有CPU都忙于使用多个GM进程处理其他图像,那么允许GM使用多个线程将增加开销并降低总体吞吐量。