在实现快速图像绘制到窗口时,目前的最佳做法是什么?我说的是一些非常简单的东西,比如一个带有2缓冲区缓冲策略的JFrame。 (当前)最快的方法是什么?
我已经读过VolatileImage硬件加速的地方,而BufferedImage是管理的,除非可能不再这样,因为随着每次新的更新(+ Java 7的发布),这可能不再是这种情况,因为Java加速了更多,更多BufferedImage等等。
所以(一般来说)你对使用这些条件实现快速图像绘制的建议是什么:
在有人要求我试图对这两个进行基准测试之前,我发现我的硬件几乎没有差别。然而,我听说这可能与硬件有关,所以我真的只是在寻找现代最佳实践。
答案 0 :(得分:2)
从我的移动线程“BufferedImage vs VolatileImage - PERFORMANCE COMPARISON”(编辑和改进):
我最近发现了一个关于VolatileImage的post on JavaGaming.org,与BufferedImage相比,它的性能非常出色。我自己在一个矿山项目中试过它,它的优势显而易见! 但是像我一样挑剔,我希望看到数字形式的结果,这就是我想出的结果:
我决定创建一个小程序,为我提供一些基准测试结果,以比较不同条件下的两种图像类型。
该计划:基准测试方法很简单。 2K(2560x1440)测试图像缩小为HD(1280x720),然后绘制到BufferedImage或VolatileImage(我使用BufferedImage来存储测试图像,因为测试表明我用它存储的图像类型没有区别) 。然后有两种变体: 1st 当测试图像被绘制到Buffered-或VolatileImage时,Buffered-或VolatileImage会在同一循环运行中被绘制到帧的JPanel。 2nd 测试图像在Volatile-或BufferedImage上被绘制n次,然后才被绘制到JPanel。该程序记录两个测试(1st BufferedImage,2nd VolatileImage)的执行需要多长时间并在控制台中打印出来。我还测试了如果你使用相同的测试图片和alpha通道(透明度)的结果,因为我经常看到有人声称VolatileImage会有问题。
结果:我在Mac Minit(2012年末)运行程序,搭载2.5 ghz的Intel i5双核。使用的Java版本是v8_112,通过Eclipse执行。以下是我的结果:
Test-methodology 1 - no transparency:
Num of Repeats: BufferedImage: VolatileImage:
200 3.280 Seconds 0.784 Seconds
500 8.230 Seconds 1.818 Seconds
1000 16.030 Seconds 3.666 Seconds
Test-methodology 1 - transparancy:
Num of Repeats: BufferedImage: VolatileImage:
200 4.166 Seconds 0.806 Seconds
500 10.636 Seconds 1.793 Seconds
1000 20.565 Seconds 3.514 Seconds
Test-methodology 2 - no transparancy:
Num of Repeats: BufferedImage: VolatileImage:
200 1.165 Seconds 0.093 Seconds
500 2.862 Seconds 0.104 Seconds
1000 5.770 Seconds 0.112 Seconds
Test-methodology 2 - transparancy:
Num of Repeats: BufferedImage: VolatileImage:
200 2.389 Seconds 0.120 Seconds
500 5.986 Seconds 0.128 Seconds
1000 11.902 Seconds 0.134 Seconds
当然,很多关于性能的信息取决于图像的实现和使用方式。在我的情况下,作为缓冲区,允许我做一些事情,如淡化整个图像。但是,您仍然可以找到两种图像类型的显着下降和上升:
通常,测试中的VolatileImage似乎比BufferedImage快得多(4到6倍)。当我在一个小游戏中使用相同的实现时,在非综合测试中获得了类似的结果。但是在我的测试中,我遇到了一种实现方式(遗憾的是,我无法重构它),它向我展示了VolatileImage不是永远的方式(是的,它在这种情况下比竞争对手慢)。
考虑到透明度,两种图像类型均匀缩放,但VolatileImage似乎没有像BufferedImage那样快速地丢失,尽管添加了alpha通道。
我想提一下:在我的测试中,循环次数较少(1-10),我发现,BufferedImage在绘制单帧时要快得多。特别是在渲染透明图像时。单帧使BufferedImage大约0.03秒,VolatileImage需要0.035。当使用大约3到6个循环时,差距变得更大。只有在8到10之间,VolatileImage占据了领域并且随着循环次数的增加而变得更好......
我想用你的意见(由测试支持)扩展这个结论,并且还想知道你出现的那两个图像的哪些实现以及它们在那里的变化。
就个人而言,我将来会使用VolatileImage进行渲染。 BufferedImage将成为我的日常驱动程序,用于存储图像,然后在渲染循环中绘制。主要是因为我发现它们更容易处理(有一种方法可以将BI转换为VI,但这是另一个时间的故事)。我也期待Java 9,这个已经在今年12月宣布但似乎被推迟了,并将再次运行我的测试。
我上传了source code on GitHub。您可以查看它,如果您愿意,可以自己动手试试吧!
答案 1 :(得分:0)
是否有任何官方文件或基准有助于证明这一点?
不是我知道的。但是,您可以修改此Java 2D基准来比较两种方法:http://www.randelshofer.ch/oop/graphics/index.html
(关于Java基准测试的标准警告适用......)