您的位置 首页 java

他们说Java 性能已经达到甚至超过 C++?

游戏/CAD本来就是C++的核心阵地,特别难被其它语言取代。(科学计算/网络服务方面的强势则更多是惯性使然)在这个场景下Java和C++有明显的性能差距,不代表别的场景下两者性能不能接近。
这类场景的特点是什么呢?操作一大堆各种类型小对象的复杂代码。

  1. 大量小对象
  2. 多种类型
  3. 代码量大

缺一不可。
这类任务说到底就是模拟。Bjarne Stroustrup创造C++就是为了做模拟,并非偶然。

Memory wall是越来越高的。 Memory is the new disk. 对于这类任务,不是说你JIT生成了理论上最少cycle数的代码,性能就比肩C/C++了,还要看对象的内存布局。内存布局不能和C/C++一样紧凑的话,可能从起跑线上就已经输了。
比如最简单的对象:

 struct Point {
    float x;
    float y;
    float z;
};
  

C/C++的内存布局:

他们说Java 性能已经达到甚至超过 C++?

不可能比这更紧凑了。
再看Java(当然,与 JVM 具体实现相关):

他们说Java 性能已经达到甚至超过 C++?

多出这12 bytes可能就是内循环能不能放进L1 cache,或者对象能不能放进一个cache line的区别(后者具体到这个例子里没问题)。
Java 毕竟还有primitive types。换成一些 脚本语言 ,比如Python,每个float还有自己的header,那更没法看了。这是一个struct。如果有嵌套的情况:

 struct Line {
    struct Point begin;
    struct Point end;
};
  

C/C++:

他们说Java 性能已经达到甚至超过 C++?

Java:

他们说Java 性能已经达到甚至超过 C++?

这就不只是多几个 byte ,还多了间址,有数据依赖。
再看数组:

 struct Point v[100];
  

C/C++:

他们说Java 性能已经达到甚至超过 C++?

Java:

他们说Java 性能已经达到甚至超过 C++?

内存访问局部性差距比较大。回头看前面说的3点:

  1. 大量小对象
  2. 多种类型
  3. 代码量大

如果对象都是大块连续内存,比如1MB的文本块,那么object header和间址的开销就被吸收了。

如果不是类型多和代码量大,那么你不太需要C++的抽象能力,完全可以用C。

另一方面,如果类型少,你即使用Java也可以绕过语言的类型系统自己控制布局。比如 Hive 根本上只有Record一种对象重要,它就可以让Record大部分时间以序列化之后的形式作为内存中的一段连续字节,回避了以上各种开销。

而如果任务同时具备以上3个特点,那么对于Java(和其它高级语言),如果不能把内循环访问的对象的内存布局优化到和C/C++基本一致,那么即使JIT再先进,性能也难以接近C/C++。
所以你看到microbenchmark里JIT表现出色的往往是Fibonacci这种只涉及int和int[]的短循环/递归。别说Java JIT了,就是Python,PyPy在这类benchmark上也表现不错。然而就此推测PyPy开发游戏引擎的表现就不太靠谱。

对于JVM来说,Project Valhalla和Azul Systems的ObjectLayout似乎都在程序员手动生成近似C/C++的内存布局上下功夫。而对于VM/JIT自动优化内存布局,是否有人做,难点在哪里,在下孤陋,@RednaxelaFX能否指点一二?

文章来源:智云一二三科技

文章标题:他们说Java 性能已经达到甚至超过 C++?

文章地址:https://www.zhihuclub.com/185261.shtml

关于作者: 智云科技

热门文章

评论已关闭

10条评论

网站地图