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似乎是永恒的,选择将完全不同。
翻译自: https://www.javacodegeeks.com/2013/09/speed-up-with-fast-java-and-file-serialization.html
java文件序列化
java文件序列化_通过快速Java和文件序列化加快速度相关推荐
- java 判断类型_如何快速入门Java编程学习(干货)
一.初识Java 1.生活中的程序: 从起床到教室上课的过程 穿衣打扮>起床>洗漱>出宿舍>>吃早餐>到教室 按照特定的顺序去完成某一件事的过程我们叫做生活中的程序 ...
- fegin调用为什么要序列化_全方位解析Java的序列化
前言 相信大家日常开发中,经常看到Java对象"implements Serializable".那么,它到底有什么用呢?本文从以下几个角度来解析序列这一块知识点~ 什么是Java ...
- 什么是java序列化_什么是Java序列化?为什么序列化?序列化有哪些方式?
先普及一下,计算机中无法识别一个基本单元[字节]来表示,必须经过"翻译"才能让计算机理解人类的语言,这个翻译过程就是[编码],通常所说的字符转换为字节. ?有I/O的地方机就会涉及 ...
- java序列化_技术干货 | JAVA反序列化漏洞
目录 反序列化漏洞 序列化和反序列化 JAVA WEB中的序列化和反序列化 对象序列化和反序列范例 JAVA中执行系统命令 重写readObject()方法 Apache Commons Collec ...
- java序列化_今天聊聊 Java 序列化
点击上方 Java后端,选择 设为星标 优质文章,及时送达在开发过程中经常会对实体进行序列化,但其实我们只是在"只知其然,不知其所以然"的状态,很多时候会有这些问题: 什么是序列化 ...
- java序列化_深入学习Java序列化
前言 对于Java的序列化,一直只知道只需要实现Serializbale这个接口就可以了,具体内部实现一直不是很了解,正好这次在重复造RPC的轮子的时候涉及到序列化问题,就抽时间看了下 Java序列化 ...
- java io 文件复制_实例讲述Java IO文件复制
前言:IO流主要分为两大类,分别是字节流与字符流 注意: 1.音频文件.图片.视频(范围广),就用字节流 2.只涉及到文本的,就用字符流 使用字节流复制文本内容(其他文件也可以) 代码如下: impo ...
- easyloging 获取日志文件名字_愉快地学Java语言:第十五章 断言与日志
导读 本文适合Java入门,不太适合Java中高级软件工程师.本文以<Java核心技术基础知识卷I>第10版为蓝本,采用不断提出问题,然后解答问题的方式来讲述.本篇文章只是这个系列中的一篇 ...
- java io 文件路径_如何从Java项目中的相对路径读取文件? java.io.File找不到指定的路径...
如何从Java项目中的相对路径读取文件? java.io.File找不到指定的路径 我有一个包含2个包的项目: ListStopWords.txt ListStopWords.txt 在包(2)中我有 ...
最新文章
- 在dw下安装zen coding,并对其快捷键进行修改
- Nginx Rewrite规则初探
- 妙趣横生算法 3:寻找相同元素的指针
- session很快失效_一口气说出 4 种分布式一致性 Session 实现方式,面试杠杠的~
- 段错误、内存泄漏、内存溢出、堆溢出、栈溢出
- [Unity][NodeCanvas] 通过 .value 获取 BBParameter 黑板值
- 大数据之-入门_大数据部门组织结构(重点)---大数据之hadoop工作笔记0007
- Factory method ‘redisConnectionFactory‘ threw exception; nested exception is java.lang.NoClassDefFou
- solr查询如何支持多个fq 多条件查询
- 如何配置Modbus读写器
- Windows 使用 CMD 命令行下载文件
- 知网查重报告html乱码,知网查重报告出现乱码怎么办
- Element.closest() 兼容IE
- Flutter之国际化语言
- android-下拉更多列表
- echarts关系图指向混乱
- optimizeinplace
- 防反保护电路的设计(下篇)
- 软考-嵌入式系统设计师:[多媒体技术:笔记(四)]
- MIPS架构——汇编代码转机器代码编译器 Matlab GUI
热门文章
- [XSY4197] Snow(树形DP)
- Sentinel(二十五)之Sentinel Dashboard同步Apollo存储规则
- 当你「ping 一下」的时候,你知道它背后的逻辑吗
- HtmlParser提取网页中的纯文本信息
- [初级]Java命令学习系列(七)——javap
- 对ASCALL码的理解
- jdk的安装与环境变量的配置
- hibernate正向生成数据库表以及配置——Teacher.hbm.xml
- 2020蓝桥杯省赛---java---B---1(门牌制作)
- 2015蓝桥杯省赛---java---C---3(无穷分数)