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文件序列化

java文件序列化_通过快速Java和文件序列化加快速度相关推荐

  1. java 判断类型_如何快速入门Java编程学习(干货)

    一.初识Java 1.生活中的程序: 从起床到教室上课的过程 穿衣打扮>起床>洗漱>出宿舍>>吃早餐>到教室 按照特定的顺序去完成某一件事的过程我们叫做生活中的程序 ...

  2. fegin调用为什么要序列化_全方位解析Java的序列化

    前言 相信大家日常开发中,经常看到Java对象"implements Serializable".那么,它到底有什么用呢?本文从以下几个角度来解析序列这一块知识点~ 什么是Java ...

  3. 什么是java序列化_什么是Java序列化?为什么序列化?序列化有哪些方式?

    先普及一下,计算机中无法识别一个基本单元[字节]来表示,必须经过"翻译"才能让计算机理解人类的语言,这个翻译过程就是[编码],通常所说的字符转换为字节. ?有I/O的地方机就会涉及 ...

  4. java序列化_技术干货 | JAVA反序列化漏洞

    目录 反序列化漏洞 序列化和反序列化 JAVA WEB中的序列化和反序列化 对象序列化和反序列范例 JAVA中执行系统命令 重写readObject()方法 Apache Commons Collec ...

  5. java序列化_今天聊聊 Java 序列化

    点击上方 Java后端,选择 设为星标 优质文章,及时送达在开发过程中经常会对实体进行序列化,但其实我们只是在"只知其然,不知其所以然"的状态,很多时候会有这些问题: 什么是序列化 ...

  6. java序列化_深入学习Java序列化

    前言 对于Java的序列化,一直只知道只需要实现Serializbale这个接口就可以了,具体内部实现一直不是很了解,正好这次在重复造RPC的轮子的时候涉及到序列化问题,就抽时间看了下 Java序列化 ...

  7. java io 文件复制_实例讲述Java IO文件复制

    前言:IO流主要分为两大类,分别是字节流与字符流 注意: 1.音频文件.图片.视频(范围广),就用字节流 2.只涉及到文本的,就用字符流 使用字节流复制文本内容(其他文件也可以) 代码如下: impo ...

  8. easyloging 获取日志文件名字_愉快地学Java语言:第十五章 断言与日志

    导读 本文适合Java入门,不太适合Java中高级软件工程师.本文以<Java核心技术基础知识卷I>第10版为蓝本,采用不断提出问题,然后解答问题的方式来讲述.本篇文章只是这个系列中的一篇 ...

  9. java io 文件路径_如何从Java项目中的相对路径读取文件? java.io.File找不到指定的路径...

    如何从Java项目中的相对路径读取文件? java.io.File找不到指定的路径 我有一个包含2个包的项目: ListStopWords.txt ListStopWords.txt 在包(2)中我有 ...

最新文章

  1. 在dw下安装zen coding,并对其快捷键进行修改
  2. Nginx Rewrite规则初探
  3. 妙趣横生算法 3:寻找相同元素的指针
  4. session很快失效_一口气说出 4 种分布式一致性 Session 实现方式,面试杠杠的~
  5. 段错误、内存泄漏、内存溢出、堆溢出、栈溢出
  6. [Unity][NodeCanvas] 通过 .value 获取 BBParameter 黑板值
  7. 大数据之-入门_大数据部门组织结构(重点)---大数据之hadoop工作笔记0007
  8. Factory method ‘redisConnectionFactory‘ threw exception; nested exception is java.lang.NoClassDefFou
  9. solr查询如何支持多个fq 多条件查询
  10. 如何配置Modbus读写器
  11. Windows 使用 CMD 命令行下载文件
  12. 知网查重报告html乱码,知网查重报告出现乱码怎么办
  13. Element.closest() 兼容IE
  14. Flutter之国际化语言
  15. android-下拉更多列表
  16. echarts关系图指向混乱
  17. optimizeinplace
  18. 防反保护电路的设计(下篇)
  19. 软考-嵌入式系统设计师:[多媒体技术:笔记(四)]
  20. MIPS架构——汇编代码转机器代码编译器 Matlab GUI

热门文章

  1. [XSY4197] Snow(树形DP)
  2. Sentinel(二十五)之Sentinel Dashboard同步Apollo存储规则
  3. 当你「ping 一下」的时候,你知道它背后的逻辑吗
  4. HtmlParser提取网页中的纯文本信息
  5. [初级]Java命令学习系列(七)——javap
  6. 对ASCALL码的理解
  7. jdk的安装与环境变量的配置
  8. hibernate正向生成数据库表以及配置——Teacher.hbm.xml
  9. 2020蓝桥杯省赛---java---B---1(门牌制作)
  10. 2015蓝桥杯省赛---java---C---3(无穷分数)