java文件序列化_通过快速Java和文件序列化加快速度

java文件序列化

从Java的第一个版本开始,许多开发人员每天都在努力实现至少与C / C ++一样好的性能。 JVM供应商正在通过实现一些新的JIT算法来尽力而为,但仍有许多工作要做,尤其是在我们如何使用Java方面。

例如,对象<->文件序列化有很多优势,尤其是在写入/读取可以轻松放入内存的对象方面。 我将尝试阐明该主题。

所有测试都在下面显示的简单对象上执行:

public class TestObject implements Serializable {private long longVariable;private long[] longArray;private String stringObject;private String secondStringObject; //just for testing nulls/* getters and setters */
}

为了更简洁,我将仅显示write方法(尽管另一种方法也非常相似)。 完整的源代码可在我的GitHub(http://github.com/jkubrynski/serialization-tests)上找到。

最标准的Java序列化(我们都从这里开始)如下所示:

public void testWriteBuffered(TestObject test, String fileName) throws IOException {ObjectOutputStream objectOutputStream = null;try {FileOutputStream fos = new FileOutputStream(fileName);BufferedOutputStream bos = new BufferedOutputStream(fos);objectOutputStream = new ObjectOutputStream(bos);objectOutputStream.writeObject(test);} finally {if (objectOutputStream != null) {objectOutputStream.close();}}
}

加快标准序列化的最简单方法是使用RandomAccessFile对象:

public void testWriteBuffered(TestObject test, String fileName) throws IOException {ObjectOutputStream objectOutputStream = null;try {RandomAccessFile raf = new RandomAccessFile(fileName, "rw");FileOutputStream fos = new FileOutputStream(raf.getFD());objectOutputStream = new ObjectOutputStream(fos);objectOutputStream.writeObject(test);} finally {if (objectOutputStream != null) {objectOutputStream.close();}      
}

更复杂的技术是使用Kryo框架。 新旧版本之间的差异很大。 我都检查了。 因为性能比较没有发现任何明显的不同,所以我将重点介绍第二个版本,因为它更加用户友好,甚至更快。

private static Kryo kryo = new Kryo(); // version 2.xpublic void testWriteBuffered(TestObject test, String fileName) throws IOException {Output output = null;try {RandomAccessFile raf = new RandomAccessFile(fileName, "rw");output = new Output(new FileOutputStream(raf.getFD()), MAX_BUFFER_SIZE);kryo.writeObject(output, test);} finally {if (output != null) {output.close();}}
}

最后一个选择是受Martin Thompson文章启发的解决方案。 它显示了如何以C ++方式和Java处理内存

public void testWriteBuffered(TestObject test, String fileName) throws IOException {RandomAccessFile raf = null;try {MemoryBuffer memoryBuffer = new MemoryBuffer(MAX_BUFFER_SIZE);raf = new RandomAccessFile(fileName, "rw");test.write(memoryBuffer);raf.write(memoryBuffer.getBuffer());} catch (IOException e) {if (raf != null) {raf.close();}}
}

TestObject的写入方法如下所示:

public void write(MemoryBuffer unsafeBuffer) {unsafeBuffer.putLong(longVariable);unsafeBuffer.putLongArray(longArray);// we support nullsboolean objectExists = stringObject != null;unsafeBuffer.putBoolean(objectExists);if (objectExists) {unsafeBuffer.putCharArray(stringObject.toCharArray());}objectExists = secondStringObject != null;unsafeBuffer.putBoolean(objectExists);if (objectExists) {unsafeBuffer.putCharArray(secondStringObject.toCharArray());}
}

直接内存缓冲区类(简称,只是为了展示这个主意):

public class MemoryBuffer {// getting Unsafe by reflectionpublic static final Unsafe unsafe = UnsafeUtil.getUnsafe();private final byte[] buffer;private static final long byteArrayOffset = unsafe.arrayBaseOffset(byte[].class);private static final long longArrayOffset = unsafe.arrayBaseOffset(long[].class);// other offsets private static final int SIZE_OF_LONG = 8;// other sizes private long pos = 0;public MemoryBuffer(int bufferSize) {this.buffer = new byte[bufferSize];}public final byte[] getBuffer() {return buffer;}public final void putLong(long value) {unsafe.putLong(buffer, byteArrayOffset + pos, value);pos += SIZE_OF_LONG;}public final long getLong() {long result = unsafe.getLong(buffer, byteArrayOffset + pos);pos += SIZE_OF_LONG;return result;}public final void putLongArray(final long[] values) {putInt(values.length);long bytesToCopy = values.length << 3;unsafe.copyMemory(values, longArrayOffset, buffer, byteArrayOffset + pos, bytesToCopy);pos += bytesToCopy;}public final long[] getLongArray() {int arraySize = getInt();long[] values = new long[arraySize];long bytesToCopy = values.length << 3;unsafe.copyMemory(buffer, byteArrayOffset + pos, values, longArrayOffset, bytesToCopy);pos += bytesToCopy;return values;}/* other methods */
}

卡尺运行多个小时的结果如下所示:

全程旅行[ns] 标准偏差[ns]
标准 207307 2362
英国皇家空军的标准 42661 733
KRYO 1.x 12027 112
KRYO 2.x 11479 259
不安全 8554 91

最后我们可以得出一些结论:

  • 不安全的序列化比标准使用java.io.Serializable的速度快23倍以上
  • 使用RandomAccessFile可以将标准缓冲序列化速度提高近4倍
  • Kryo动态序列化比手工实现的直接缓冲区慢约35%。

最后,正如我们所看到的,仍然没有金锤。 对于我们很多人来说,获得3000 ns(0.003ms)的时间不值得为我们要与文件序列化的每个对象编写自定义实现。 对于标准解决方案,我们主要选择Kryo。 但是,在低延迟系统中,100ns似乎是永恒的,选择将完全不同。

参考:来自Java(B)Log博客的JCG合作伙伴 Jakub Kubrynski的快速Java和文件序列化加速。

翻译自: https://www.javacodegeeks.com/2013/09/speed-up-with-fast-java-and-file-serialization.html

java文件序列化

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

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

相关文章

【黑客帝国数字雨屏保】基于Win32的黑客帝国数字雨屏幕保护程序(附VS工程代码文件和可执行文件)

运行效果 代码结构 //黑客帝国数字雨 花心胡萝卜 #包含 <windows.h> #包含 <stdlib.h>#define 时钟编号 1 #define 最大长度 25 //一个显示列的最大长度 #define 最小长度 8 //一个显示列的最小长度 // 类型定义 结构类型 _字符序列 {//整个当作屏幕的一个显示列…

TestContainers和Spring Boot

TestContainers太棒了&#xff01; 它提供了一种非常方便的方式来启动和清除JUnit测试中的Docker容器。 此功能对于将应用程序与实际数据库以及可使用docker映像的任何其他资源进行集成测试非常有用。 我的目标是演示使用TestContainers对基于JPA的Spring Boot Application进行…

【模式识别】信号检测实验及MATLAB仿真

一、 参数 高斯噪声均值 u = 0 u = 0 u=0,方差 σ = 1 \sigma =

【模式识别】Fisher线性判别实验报告之MATLAB仿真

一、 参数 1.题设三个类,每个类均有10个样本,分别为w1,w2,w3,因此采用两两互相分类,最后得出结果; 2.三类样本的均值向量依次为m1,m2,m3; 3.三类样本的类内离散度矩阵依次为S1,S2,S3; 4.对于w1和w2,总类内离散度矩阵为Sw12,类间离散度矩阵为Sb12,通过矩阵特…

不知所措:您是否真的需要为您的API提供客户端库?

RESTful Web服务和API的优点在于&#xff0c;任何使用HTTP协议的使用者都可以理解和使用它。 但是&#xff0c;同样的难题一遍又一遍地弹出&#xff1a;您是否应该将Web APis与客户端库一起使用&#xff1f; 如果是&#xff0c;您应该支持哪些语言或/和框架&#xff1f; 通常这…

【模式识别】K均值聚类算法应用实验报告及MATLAB仿真

一、 实验目的 1.掌握K均值聚类算法的原理和实现过程; 2.掌握K均值聚类算法的应用方法。 二、 实验内容 1.彩色图像分割 选择一幅图像,分别按三种颜色数进行彩色图像分割的结果(原图和分割图)。步骤如下: (1) 第一步:读入一幅rgb图像并显示; (2) 第二步:将该幅图…

【模式识别】特征评价和可分性判据实验报告及MATLAB仿真

一、 实验目的 1.掌握几种常用的特征评价方法和可分性判据; 2.解图像阈值分割中几种确定阈值的方法。 二、 实验原理 假设图像中出现的最大灰度级为m,阈值为g,目标部分灰度均值为mean1,像素数占整个图像比例为w1;背景部分灰度均值为mean2,像素数占整个图像比例为w2。…

web应用插件开发_Web应用程序的简单插件系统

web应用插件开发我们需要制作多个具有很多共享功能的基于Web的项目。 为此&#xff0c;某种插件系统将是一个不错的选择&#xff08;作为粘贴粘贴内容的替代方法&#xff09;。 有些框架&#xff08;例如grails&#xff09;可以选择制作Web插件&#xff0c;但大多数没有&#x…

【自适应盲均衡2】多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真

关注公号【逆向通信猿】更精彩!!! 关于均衡的基础知识,首先可参考本人博客 LMMSE、Godard、CMA常模、Sato等算法在信道均衡中的应用理论与MATLAB仿真 理论推导 代价函数 J = E [ e G o d a r d p

【自适应盲均衡3】多模算法(MMA)——复数改进常模算法(MCMA)的理论推导与MATLAB仿真

关注公号【逆向通信猿】更精彩!!! 接上篇【自适应均衡2】多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真 理论推导 MMA或者MCMA其实是在CMA基础上改进而得到的,有学者称其为实虚部分开的常模算法。该算法使均衡器输出信号的实部与虚部分别收敛于各自的模值,改…

程序猿必备工具『CSDN浏览器助手』之超实用小工具测评

CSDN浏览器助手简介 CSDN浏览器助手由CSDN官方开发&#xff0c;集成【一键呼出搜索】、【万能快捷工具】、【个性标签页】和【 “真”免广告】四大功能&#xff0c;打开后给人的第一印象就是 清新脱俗 四个字&#xff0c;功能非常丰富&#xff0c;快捷键的使用能够大大提高工作…

【自适应盲均衡4】基于RLS的多径衰落信道均衡算法(RLS-CMA)的理论推导与MATLAB仿真

关注公号【逆向通信猿】更精彩!!! 一、回顾CMA和MMA 对于前面两种算法 【自适应均衡】多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真 【自适应均衡】多模算法(MMA)——复数改进常模算法(MCMA)的理论推导与MATLAB仿真 误差信号为:

apache camel_使用Java的Apache Camel入门

apache camelApache Camel是一个非常有用的库&#xff0c;可以帮助您处理来自许多不同来源的事件或消息。 您可以通过许多不同的协议&#xff08;例如在VM&#xff0c;HTTP&#xff0c;FTP&#xff0c;JMS甚至DIRECTORY / FILE之间&#xff09;移动这些消息&#xff0c;但仍然使…

【自适应(盲)均衡6】信号过多径衰落信道的矩阵乘法表示之Toeplitz矩阵和Toeplitz块矩阵的生成(分数间隔FSE)

关注公号【逆向通信猿】更精彩!!! 信号过系统(多径信道)的连续形式 信号过系统(多径信道)的离散采样形式 通常接收端处理的是数字信号,需对接收信号进行采样,当采样率为符号速率时,即为符号间隔采样;采样率为符号速率的P倍时,为分数间隔采样 至于为什么要用分数…

JDK 9/10/11:Java字符串上+ =带来的副作用

问题“ 为什么array [i &#xff05;n] i ”在Java 8和Java 10中给出不同的结果&#xff1f; ”已于本周初发布在StackOverflow.com上 。 它指向JDK9和更高版本中存在的Java编译器中的错误 &#xff0c;但JDK8中不存在。 如StackOverflow线程上所述&#xff0c; Didier L提供…

Matlab库中过采样函数rcosflt参数及源代码详解(翻译)

函数定义 rcosflt函数作为MATLAB即将被替换的函数,在MATLAB R2018b中还可以使用,但是已经查不到帮助文档;虽说是要即将被替换,但是函数内部的原理其实都是一样的,这个函数搞懂了,不管被替换成什么,只要看看新函数的说明文档就知道怎么使用了,说白了就是“万变不离其宗…

【自适应盲均衡7】分数间隔的复数常模算法(FSE-CMA)

关注公号【逆向通信猿】更精彩!!! 理论推导 基于分数间隔的复数常模算法(FSE-CMA)的推导其实与符号间隔的算法是类似的,见 【自适应盲均衡2】多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真 分数间隔均衡器模型 分数间隔均衡器通常有两种比较经典的模型,…

Java机器学习,第2部分

欢迎使用本教程的第二部分&#xff0c;该教程使用LightningScorer评分PMML文件。 让我们找出其他参数是如何工作的。 初始步骤与教程的第一部分相似。 首先获取本地副本 git clone https://github.com/sezinkarli/lightningscorer.git并用Maven构建 mvn clean install并通…

【自适应盲均衡8】基于分数间隔的复数改进常模算法(FSE-MMA)的瑞利衰落信道盲均衡MATLAB仿真

关注公号【逆向通信猿】更精彩!!! 知识回顾 关于最基本的盲均衡算法,即CMA盲均衡的原理、推导与MATLAB仿真,可以参考 【自适应盲均衡2】多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真 关于改进的CMA算法,即MMA的原理、推导与MATLAB仿真,可以参考 【自适应盲…

JavaFX技巧30:带有DropShadow的ScrollPane

最近&#xff0c;在我的一个项目中&#xff0c;我发现用户很难看到ScrollPane实例的内容当前是否已滚动。 一种更清晰的方法是在滚动窗格的顶部添加阴影。 这也是Google的Material Design建议的。 所以我尝试了一下。 在我的解决方案中&#xff0c;我只是向ScrollPane添加了一…