如何在Java中获得类似于C的性能

总览

Java有许多可能很慢的领域。 但是,对于每个问题都有解决方案。 许多解决方案/黑客都需要解决Java的保护问题,但是如果您需要低水平的性能,还是可以的。

Java使高级编程变得更简单容易,但代价是使低级编程变得更加困难。 幸运的是,大多数应用程序都遵循经验法则,即您将90%的时间花费在10%的代码中。 这意味着您有90%的时间状况良好,而有10%的时间状况较差。 ;)

这让我想知道为什么对于大多数项目,您会用C / C ++编写超过10%的代码。 在某些项目中,C / C ++是唯一明智的解决方案,但是我怀疑大多数C / C ++项目都可以通过使用Java之类的高级语言来提高生产力。

获得类似C的性能的一种方法是通过JNI将C用于代码的关键部分。 如果要避免使用C或JNI,仍然可以通过多种方法获得所需的性能。

注意:这些建议大多数仅适用于独立应用程序,而不适用于applet。

注意2:使用风险自负。 您可能需要测试使用低级Java时通常不需要担心的极端情况。

快速阵列访问

Java可能较慢的一个方面是数组访问。 这是因为它隐式地进行边界检查。 JVM足够聪明,可以通过检查第一个和最后一个元素来优化循环检查,但这并不总是适用。

一种解决方法是使用Unsafe类(该类仅在某些JVM上可用,而OpenJDK JVM才可用)。该类为每种基本类型都具有getXxxx()和setXxxx(),并允许您直接访问对象,数组或直接内存,其中您必须进行边界检查。 在本机代码中,这些被编译为单个机器代码指令。 还有一个getObject(),setObject()方法,但是我怀疑它们不能提供很多性能改进(在您访问对象时也是如此)

您可以通过下载OpenJDK的调试版本并获取其打印已编译的本机代码来检查为方法生成的本机代码。

任意内存访问

您可以再次使用Unsafe类进行任意访问,但是“更友好”的方法是使用DirectByteBuffer并根据需要更改其地址和限制(通过反射或通过JNI)。这将为您提供一个Buffer,它指向一个随机区域。内存,例如设备缓冲区。

使用更少的内存

这已不再是一个问题。 一台16 GB的服务器售价为1000美元,一台1 TB的服务器售价约为7万美元。

但是,缓存仍然是一种溢价,对于某些应用程序而言,它值得减少内存消耗。 一个简单的事情是使用Trove ,它可以有效地支持集合中的原语。 如果数据表很大,则可以按列而不是按行存储数据(如果有很多行数据和几列数据)。 如果您要按字段扫描数据但不需要所有字段,则可以改善缓存行为。

您还可以使用直接存储器按需要存储数据。 这就是BigMemory库所使用的。

基于流的IO速度很慢,NIO很难使用

如何利用您的两全其美? 在NIO中使用阻塞IO(这是通道的默认设置)除非需要选择器,否则不要使用选择器。 在许多情况下,它们只会增加复杂性。 大多数系统可以有效处理1K-10K线程。 如果您需要更多的连接,请购买另一台服务器,一台便宜的服务器大约需要500美元。

快速高效的字符串

Java 6 update 21具有选项-XX:+ UseCompressedStrings,对于不需要16位字符的字符串,可以使用byte []代替char []。 对于许多应用程序,这可以节省内存,但速度较慢。 (5%-10%)

相反,您可以使用自己的Text类型来包装byte [],或者从ByteBuffer,CharBuffer中获取文本数据或使用Unsafe。

更快的启动时间

当您加载许多肿的库时,Java的启动时间往往很慢。 如果这确实是一个问题,那么您加载较少的库。 无论如何,将它们保持在最低水平是一个好习惯。 这样做,您的启动时间将为几秒钟(不及C快,但可能足够快)

更少的GC暂停

大多数Java库都是自由创建对象的,通常这不是问题。

但是,这并不意味着您不能预先分配对象,不能使用直接字节缓冲区和对象回收技术来最大程度地减少对象的创建。 通过增加Eden大小,您可以拥有很少使用GC的应用程序。 您甚至可以将其每天减少到一个GC(例如按计划的通宵工作)

参考: 如何Vanilla Java的 JCG合作伙伴 Peter Lawrey 获得Java的C类性能

相关文章:

翻译自: https://www.javacodegeeks.com/2011/07/how-to-get-c-like-performance-in-java.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值