java bufferarray_Java缓冲区类型与原生数组:哪个更快?

原标题:Java缓冲区类型与原生数组:哪个更快?

使用 C 语言开发时,必须手动分配和释放内存,这是一个容易出错的过程。相反,像 Java 这样的之后的一些语言通常会自动管理内存。Java 依赖于垃圾回收。实际上,内存是根据需要来分配,然后 Java 发现哪些数据不再访问,并回收相应的内存。垃圾回收过程既快速又安全,但是它不是免费的:尽管进行了数十年的优化,但它仍然可能给开发人员带来一些麻烦。

Java 具有原生数组(例如 int[] 类型),这些数组通常在 Java 堆上分配。也就是说,它们由 Java 作为动态数据进行分配和管理,并进行垃圾回收。

Java 还具有 Buffer 类型,如 IntBuffer,它是一种高级抽象,可以由原生 Java 数组实现,也可以由其他数据源(包括 Java 堆外数据)来实现。因此,可以使用 Buffer 类型来避免过多地依赖 Java 堆。

与原生数组相比,Buffer 会存在一定性能损失。我不是说 Buffer 慢。事实上,如果在 Buffer 和流(DataInputStream)之间做一个选择,你应该更倾向于 Buffer 类型。然而,根据我的经验,Buffer 在性能方面不如原生数组。

我可以用 new int[50000] 或 IntBuffer.allocate(50000) 来创建一个包含 50,000 个整数的数组。后者本质上应该是创建一个数组(在 Java 堆上),然后用 IntBuffer 接口来包装。

一个可能的直觉是,用高级接口包装一个数组应该是免费的。虽然高层次的抽象确实可以不带来性能上的损失(有时甚至可以带来性能上的提升),但是否会带来性能上的提升是一个经验问题。你绝对不应该只是假设你的抽象是免费得来的。

因为我在做一个经验陈述,但我可以用最简单的测试来证明它,比如给数组 以及 IntBuffer 中的每个元素加 1。

for( intk = 0; k < s. array.length; k++) {

s. array[k] += 1;

}

for(int k = 0; k < s.buffer.limit; k++) {

s.buffer.put(k, s.buffer.get(k) + 1);

}

我在台式机(OpenJDK 14,4.2 GHz Intel 处理器)上得到结果如下:

eba6be03141b88137aaaaeaf8bfc30a8.png

也就是说,在此测试中,数组比 IntBuffers 快 4 倍以上。

如果有兴趣,你也可以自己运行以下基准测试。

https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2020/11/30

我的看法是,Java 针对数组的许多优化不适用于 Buffer 类型。

当然,我们无法得知 Buffer 从 Java 堆外映射时发生了什么,根据我的经验,情况可能很糟。

Buffer 类型并不会让原生数组过,至少在性能方面。

英文原文(包含一些精彩评论):

https://lemire.me/blog/2020/11/30/java-buffer-types-versus-native-arrays-which-is-faster/

参考阅读

本文由高可用架构翻译,技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值