Java实时性能
我正在使用Java项目,该项目需要对图像进行非常高级的操作。事实上,我正在使用OpenCV进行大部分操作,我正在使用JNI来包装我需要的OpenCV函数。我对OpenCV提供的性能非常满意,编写OpenCV代码的人应该得到代码的高度赞扬。与我在Java开发人员编写的代码中的体验形成鲜明对比 我一开始对编程语言的选择持乐观态度,我的项目的第一个工作迭代运行得很好,但它的性能远没有达到实时性(大约每2秒1帧)。我对我的代码进行了一些优化,这对我很有帮助。我已经能够将帧速率提高到每秒10-20帧左右,这很好,但我发现要做进一步的优化,我必须重写Java代码来做同样的事情,但效率要提高10-20倍 Java开发人员很少关注性能,特别是在为媒体相关类编写类时,我对此感到震惊。我已经下载了OpenJDK,并且正在探索我正在使用的函数。例如,Raster类下有一个名为getPixels(…)的函数,它获取图像的像素。我希望这个函数在源代码中是一个高度优化的函数,通过多次调用System.arrayCopy来进一步优化性能。相反,我发现的是非常“经典”的代码,他们调用5-6个不同的类和10-20个不同的方法,只是为了在一行中完成我可以完成的任务:Java实时性能,java,performance,real-time,Java,Performance,Real Time,我正在使用Java项目,该项目需要对图像进行非常高级的操作。事实上,我正在使用OpenCV进行大部分操作,我正在使用JNI来包装我需要的OpenCV函数。我对OpenCV提供的性能非常满意,编写OpenCV代码的人应该得到代码的高度赞扬。与我在Java开发人员编写的代码中的体验形成鲜明对比 我一开始对编程语言的选择持乐观态度,我的项目的第一个工作迭代运行得很好,但它的性能远没有达到实时性(大约每2秒1帧)。我对我的代码进行了一些优化,这对我很有帮助。我已经能够将帧速率提高到每秒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));
}
for(int i=0;i>32;
字节红色=(字节)((p>>16)和0xff);
字节绿色=(字节)((p>>8)和0xff);
字节蓝色=(字节)((p)和0xff);
字节值=(字节)(0.212671f*红色+0.715160f*绿色+0.072169f*蓝色);
数据[i]=val;
grayFrameData[i]=(val和0x80)+(val和(0x7f));
}
上面的代码将图像转换为灰度,并在大约1-10毫秒内获得浮点像素数据。如果我想用Java内置函数做同样的事情,转换为灰度本身需要200-300毫秒,然后获取浮点像素需要大约50-100毫秒。这对实时性能来说是不可接受的。注意,要获得加速,我需要大量的时间使用逐位运算符,Java开发人员对此避而不谈
我知道他们需要处理一般情况,但即便如此,他们是否至少能给出优化选项,或者至少警告代码的执行速度有多慢
我的问题是,在开发的这个后期阶段(我已经有了我的第一次迭代,而不是我正在进行的第二次迭代的实时性更强)我应该咬紧牙关,切换到C/C++中,在那里我可以对事情进行更多的微调,还是应该坚持使用Java,希望事情变得更加实时友好,这样我就不必重写已经实现的Java代码来获得加速
我真的开始对“优雅”感到厌恶了Java的速度确实很慢。类的数量似乎有点过头了。我的建议是,这取决于图像操作相对于整个项目的重要性,以及相对于Java带来的任何优势。显然,您可以用Java编写快速代码(如您所演示的)但是,如果您的项目有80%将包含这样的优化,我肯定会重新考虑Java作为这里的语言选择 另一方面,如果这代表了应用程序的20%,而另外80%是提供此转换的用户功能,那么可能必须完成操作是一个值得的权衡,不必处理您自己的内存管理,也不必使用java为用户提供的任何其他API交互(Web、Swing、SWT,无论您使用什么) 由于垃圾收集器的存在,Java的实时性并不为人所知。这可能也会对你造成伤害,所以要小心 我的问题是,在开发的这个后期阶段(我已经有了我的第一次迭代,而不是我正在进行的第二次迭代的实时性更强)我应该咬紧牙关,切换到C/C++中,在那里我可以对事情进行更多的微调,还是应该坚持使用Java,希望事情变得更加实时友好,这样我就不必重写已经实现的Java代码来获得加速 你是在问我该不该
过早优化是万恶之源 与其抱怨,不如编写一组优化过的库并发布它们,但创建一个针对某个不存在的目标进行了预优化的“参考”java实现是错误的
参考实现的主要目的是生成可理解、可维护的代码——这是必须的。我认为,人们总是期望在必要时,供应商会分析这个可理解的版本,并重新实现部分以提高速度。除了其他人所说的,您还可以对JDK进行优化。I如果您能够提供一个强大的优化,而不牺牲通用性或可读性,我希望您能够在未来的JDK版本中包含您的补丁
因此,您不必希望JDK变得更好。您可以帮助实现它。据我所知,最新版本的Java(或者可能是
`public static final int getGrayScale(final int pixelRGB){
return (0.212671f * ((pixelRGB >> 16) & 0xff) + 0.715160f * ((pixelRGB >> 8) & 0xff) + 0.072169f * ((pixelRGB) & 0xff));
}`