我正在处理需要对图像进行非常高级操作的 Java 项目。事实上,我正在使用 OpenCV 进行大部分操作,并且我正在使用 JNI 来包装我需要的 OpenCV 函数。我对 OpenCV 提供的性能非常满意,编写 OpenCV 代码的人应该对代码给予极大的赞誉。与我对 Java 开发人员编写的代码的体验形成鲜明对比。
我开始对我的编程语言的选择持乐观态度,我的项目的第一次工作迭代运行良好,但它的性能远不接近实时(每 2 秒获得大约 1 帧。)我已经对我的代码和它帮助很大。我已经能够将帧速率提高到大约每秒 10-20 帧,这很棒,但我发现要进行任何进一步的优化,我必须重写 Java 代码来做同样的事情,但 10 -20 倍更高效。
我对 Java 的开发人员很少关注性能感到震惊,尤其是在为与媒体相关的类编写类时。我已经下载了 OpenJDK,并且正在探索我正在使用的功能。例如,在 Raster 类下有一个名为 getPixels(...) 的函数,它获取图像的像素。我期待这个函数在源代码中是一个高度优化的函数,通过多次调用 System.arrayCopy 来进一步优化性能。相反,我发现的是非常“优雅”的代码,它们调用 5-6 个不同的类和 10-20 个不同的方法,只是为了完成我可以在一行中做的事情:
for (int i =0; i < n; i++) {
long p = rawFrame[i];
p = (p << 32) >>> 32;
byte red = (byte) ((p >> 16) & 0xff);
byte green = (byte) ((p >> 8) & 0xff);
byte blue = (byte) ((p) & 0xff);
byte val = (byte)(0.212671f * red + 0.715160f * green + 0.072169f * blue);
data[i] = val;
grayFrameData[i] = (val & 0x80) + (val & (0x7f));
}
上面的代码将图像转换为灰度并获取浮点像素数据,大约需要 1-10 毫秒。如果我想对 Java 内置函数做同样的事情,转换为灰度本身需要 200-300 毫秒,然后抓取浮动像素大约需要 50-100 毫秒。这对于实时性能来说是不可接受的。请注意,为了加快速度,我大量使用了 Java 开发人员回避的位运算符。
我知道他们需要处理一般情况,但即便如此,他们至少不能提供优化选项,或者至少警告这段代码的执行速度有多慢。
我的问题是,在开发的这个后期(我已经进行了第一次迭代,而不是我正在研究实时执行更多的第二次)我是否应该硬着头皮切换到我可以很好的 C/C++更多地调整事情,或者我应该坚持使用 Java 并希望事情变得更加实时友好,这样我就不必重写已经实现的 Java 代码来获得加速。
我真的开始厌恶 Java 的“优雅”和缓慢。那里的课程数量似乎有点过头了。