使用 unsafe_使用Unsafe真的是关于速度或功能吗?

使用 unsafe

总览

大约6年前,我开始使用一个类,直到那时,它只是一个好奇心sun.misc.Unsafe 。 我曾使用它进行反序列化和重新抛出Exception,但没有使用它的全部功能或公开谈论它。

我看到的第一个严重使用Unsafe的开源库是Disruptor。 这使我感到鼓舞,它可以在稳定的库中使用。 大约一年后,我发布了我的第一个开源库SharedHashMap(后来的Chronicle Map)和Chronicle(后来的Chronicle Queue)。 它使用Unsafe来访问Java 6中的堆外内存。这对堆外内存的性能产生了真正的影响,但更重要的是,我可以使用共享内存来做。 即跨JVM共享的数据结构。

但是今天有什么不同呢? 使用不安全总是更快吗?

我们正在寻找引人注目的性能差异。 如果差异不那么明显,则使用尽可能简单的代码更有意义。 即使用自然的Java。

测试

在这些测试中,我对源自堆外内存的数据进行了简单的累积。 这是一个简单的测试,它对解析数据(或散列数据)建模,这些数据是从堆(例如,TCP连接或文件系统)中生成的。 数据大小为128个字节。 下面的结果可能受到数据大小的影响,但这被认为具有代表性。

我查看的是不同的访问大小,一次访问一个字节,一个int或一个long。 我还研究了使用ByteBuffer还是在堆上复制数据并使用自然Java(我假设这是大多数程序执行此操作的方式)。

我还比较了使用Java 6更新45,Java 7更新79,Java 8更新51的情况,以了解不同发行版之间使用不同方法的变化。

逐字节处理

处理器设计中真正改善的一点是它可以复制大型数据块的速度。 这意味着复制大量数据,以便可以更有效地处理它是有意义的。 也就是说,冗余副本可能足够便宜,从而可以带来更快的解决方案。

逐字节处理就是这种情况。 在此示例中,“在堆上”包括在处理之前在堆上复制数据的副本。 这些数字是在i7-3790X上每微秒的操作数。

Java 6 Java 7 Java 8
字节缓冲区 15.8 16.9 16.4
不安全 17.2 17.5 16.9
在堆上 20.9 22.0 21.9


这样做的重要意义在于,“堆上”不仅使用自然Java,而且在所有三个版本的Java中都是最快的。最可能的解释是,JIT具有在堆上情况下可以进行的优化。如果您直接或间接使用不安全,则不会这样做。

由int处理的int。

解析冗长的有线协议的更快方法是一次读取一个int。 例如,您可以通过一次读取一个int而不是单独查看每个字节来编写已知格式的XML解析器。 这样可以将解析速度提高2到3倍。 这种方法最适合已知结构的内容。

Java 6 Java 7 Java 8
字节缓冲区 12.6 36.2 35.1
不安全 44.5 52.7 54.7
在堆上 46.0 49.5 56.2


同样,这是i7-3790X上每微秒的操作。 有趣的是,在复制后使用自然Java大约与使用Unsafe一样快。 对于此用例,也没有令人信服的理由使用Unsafe。

长期加工

尽管您可以编写一个解析器一次读取一个64位长的值,但我发现这比使用32位int值解析要困难得多。 我也没有发现结果要快得多。 但是,只要在设计散列算法时考虑到这一点,就可以从读取长值中受益于对数据结构进行散列。

Java 6 Java 7 Java 8
字节缓冲区 12.1 56.7 53.3
不安全 66.7 83.0 94.9
在堆上 60.9 61.2 70.0


有趣的是,使用ByteBuffer的速度提高了多少。 最可能的解释是在ByteBuffer中增加了将little-endian交换为默认big-endian的优化。 x86有一条交换字节的指令,但是我怀疑Java 6没有使用它,而是使用了更昂贵的移位操作。 为了能够确认这一点,将需要进行更多的测试并检查生成的汇编代码。

在这种情况下,使用Unsafe的速度总是更快,无论您是否认为这种改进值得直接使用Unsafe带来的风险是另一回事。

补充笔记

这些测试假设使用字节,整数或长整数的统一数据类型。

在大多数实际情况下,这些数据类型是结合在一起的,这就是在堆上挣扎的地方。 例如,如果您需要解析字节,短裤,整数,长整数,浮点数,双精度数的任意组合。 ByteBuffer是执行此操作的好方法,但是在每种情况下,它都是最慢的选项。 只有不安全才能让您灵活地混合和匹配类型,而不会产生开销。

对于这些混合类型,很难对堆进行公平的测试,因为自然Java不直接支持这些操作。

结论

即使性能是您最关心的问题,在某些情况下,自然Java的性能还是更好,或与使用Unsafe一样快。 它经常执行ByteBuffer,因为JIT可以更好地优化开销,例如对自然Java代码进行边界检查。

自然的Java代码依赖于我们可以将数据建模为byte [],int []或long []的事实。 没有数组或原始类型混合的选项。

自然Java挣扎的地方在于对这两种方式的支持范围

  • 不同原始类型的任意组合,例如字节,整数,长整数,双精度数。
  • 共享/本机内存上的线程安全操作。

不幸的是,由于缺乏自然Java支持,因此很难创建公平的基准来比较性能。

总而言之,如果您可以用自然Java实现算法,那么它可能是最快也是最简单的。 如果您需要混合使用数据类型或线程安全堆进行语法分析,那么仍然没有很好的方法来使用自然Java。

注意:这是Java 9中的VarHandles应该能够提供帮助的区域,因此请观看此空间以获取VarHandles的更新。

翻译自: https://www.javacodegeeks.com/2015/08/is-using-unsafe-really-about-speed-or-functionality.html

使用 unsafe

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

securecrt哪个版本好用_电脑跑分测试软件哪个好?好用的电脑跑分软件推荐

想要直观的了解自己电脑状况,那么一款好用的电脑跑分软件无疑是必不可少的,毕竟他能够将测试结果用跑分的形式计算出来。那么,电脑跑分软件哪个比较好呢?下面是小编分享的好用的电脑跑分软件推荐,游戏玩家们可不要错过…

wildfly_从WildFly 9(子系统)中运行OkHttpClient

wildfly几天前, WildFly 9发布了,可以肯定的重点之一是Undertow Web子系统中对HTTP / 2.0的支持。 随着Hawkular最近开始使用WildFly 9(从8.2开始)作为其基础服务器,尝试使用http2连接从Hawkular-Wildfly-Monitor客户端…

C语言,单片机绕不过的坎,你对C语言内存分配了解多少呢

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删一、static在C语言里面可以用来修饰变量,也可以用来修饰函数。1、 先看用来修饰变量的时候。变量在C语言里面可分为存在全局数据区、…

setcellvalue 格式_POI对Excel单元格的格式的设置参数

最近在做导出Excel的功能封装,遇到了几个问题:单元格宽度问题数据不是数字格式问题格式化了之后显示的不是数字而是######的问题(其实是因为单元格宽度不够导致的无法显示格式化之后的内容)下面先说说解决方法:1、单元格宽度问题这个问题有两…

内存 增量数据持久_内存中数据模型和大数据持久性

内存 增量数据持久ORM框架在需要与关系数据库进行交互时可以帮助开发人员。 对于关系数据库,有许多出色的ORM框架,例如Hibernate和Apache OpenJPA,其中一些确实很棒。 如今,大数据正在涌现,越来越多的人开发在大数据上…

自学编程的6个技巧总结

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删有一天,我的一个在学编程的朋友问我:“我想快速学习编程,你有什么好的推荐吗?”我曾在上大学的时…

python就业班 miniweb框架_mini-web框架

1. 框架概述web框架是一个为web服务器提供服务的应用程序,专门负责处理用户的动态资源请求.静态资源: 资源的内容是固定不变的.动态资源: 资源的内容是动态变化, 数据是从数据库获取的.静态 web 服务器 使用 tcp 传输数据1. 导包 socket2. 创建一个 socket 对象, socket.socket…

java编写应用程序_为您的Java应用程序编写数据驱动的测试

java编写应用程序JUnit是一个功能非常强大的测试框架,它不仅为其用户提供了编写快速简便的测试的功能,而且还为用户提供了扩展它并使其按其期望的方式工作的机会。 在JUnit之上构建了许多框架,这些框架为目标受众提供了各种易用的功能。 Eas…

C语言如何知自身函数的实际地址与大小

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删事情的起因大概是这样……在很久很久以前,我最早用的是MASM(Win32ASM)写程序,从平台兼容性、开发…

python快速排序算法循环_算法:快速排序的Python实现

一、概述快速排序(quick sort)是一种分治排序算法。该算法首先 选取 一个划分元素(partition element,有时又称为pivot);接着重排列表将其 划分 为三个部分:left(小于划分元素pivot的部分)、划分元素pivot、right(大于划分元素pivot的部分)&a…

xtext_使用Xtext为Eclipse和IntelliJ开发DSL

xtext在这篇文章中,我们将看到如何开发一种简单的语言。 我们的目标是: 语言的解析器 IntelliJ的编辑器 。 编辑器应具有语法突出显示,验证和自动完成功能 我们还将免费提供Eclipse和Web编辑器的编辑器 ,但请包含您的兴奋之处&…

sed 插入多行_Linux三剑客之sed

sed命令用法小记版本:CentOS7▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼好久没更新文章了,项目的事情太多,总得给自己的懒惰找个借口,哈哈~话不多说进入正题创建测试数据[aliscaspark02 a]$ cat data#test the sedThis is the header l…

分享一些超级炫酷的C语言小技巧

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单,并且仍然有一些非常…

使用Apache Cassandra设置SpringData项目

在这篇文章中,我们将使用Gradle和spring boot来创建一个集成spring-mvc和Apache Cassandra数据库的项目。 首先,我们将从Gradle配置开始 group com.gkatzioura version 1.0-SNAPSHOTapply plugin: java apply plugin: eclipse apply plugin: idea appl…

优朋普乐大数据_优朋普乐邵以丁:用大数据全面洞察需求

优朋普乐创始人、董事长兼CEO邵以丁回顾优朋普乐十二年发展历程,数次强调是多年来积累的大数据给优朋普乐的业务拓展指明了方向,有的放矢的决策让企业对未来发展充满信心。大数据为及时发现甚至准确预测消费需求提供了新途径,因为基于相关的大…

C++编程新手容易犯的 10 种编程错误

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删公司每年都会有一定的人员流动,相应地也会招一些应届生补充进来,指导应届生已经成为老员工的必修课了。平日里会我们会经…

drill apache_Apache Drill:如何创建新功能?

drill apacheApache Drill允许用户使用ANSI SQL探索任何类型的数据。 这很棒,但是Drill的作用远远不止于此,它允许您创建自定义函数来扩展查询引擎。 这些自定义函数具有Drill基本操作的所有性能,但是允许执行这些性能会使编写这些函数的技巧…

python往npy写入数据_Python 存取npy格式数据实例

数据处理的时候主要通过两个函数(1):np.save(“test.npy”,数据结构) ----存数据(2):data np.load(test.npy") ----取数据给2个例子如下(存列表)1、z [[[1, 2, 3], [w]], [[1, 2, 3], [w]]]np.save(test.npy, z)x np.load(test.npy) x:->array([[list([1,…

Linux上C语言程序编译过程详解

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删本文将介绍如何将高层的C/C语言编写的程序转换成为处理器能够执行的二进制代码的过程,包括四个步骤:预处理(P…

hibernate 别名_Hibernate:在sqlRestriction上使用联接表别名

hibernate 别名如果在复杂查询的情况下使用Hibernate模式,则需要使用sql。 因此,sqlRestrictions可以解决。 但是,对联接表别名使用sql限制有点棘手。 将有三个表: 公司表。 员工表。 每个员工都属于一个公司,因此…