从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和文件序列化加快速度相关推荐

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

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

  2. ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler

    ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler, 使用<link type="text/css" rel="Stylesheet" ...

  3. java文件复制速度_java中文件复制得速度测试

    //需要将apache开发的两个插件包拷到lib目录下:commons-fileupload-1.2.2.jar  commons-io-2.0.1.jar package com.nay.servl ...

  4. linux rsync删文件速度,Linux下使用rsync最快速删除大量文件的方法

    要在Linux下删除海量文件的情况,需要删除三层哈希目录下的几十万个文件.这个时候,删除命令rm -rf * 就不好用了,因为要等待的时间太长.所以必须要采取一些非常手段.我们可以使用rsync来实现 ...

  5. win11如何加快搜索速度 Windows11更改文件索引加快搜索速度的设置方法

    有时候当你急需寻找一份文件的时候,可能查找筛选需要很长时间,但是有什么方法可以加快寻找文件的搜索速度呢?今天小编就为大家带来更改文件索引加快搜索速度的教程.更多Windows11安装步骤可以参考小白一 ...

  6. java之文件与IO流及序列化

    目录 文件 java操作文件原理 File类 封装文件为File类对象 常用文件方法 File对象对文件进行操作 File对象对目录进行操作 IO流 IO流的分类 节点流与处理流 处理流特点 字节流与 ...

  7. Java对象XML序列化框架-Simple2.0

    Java对象XML序列化框架-Simple2.0 Simple是一个XML序列化框架,一个Java 版本宽容的序列化框架,能够快速在Java 平台上开发XML.支持通过annotations完全配置化 ...

  8. fileinputstream自定义类序列化和反序列化_Rest Assured篇:Java中的序列化和反序列化...

    点击上方蓝字设为星标 每天傍晚伴你一起成长! Java 中的序列化和反序列化是一个重要的编程概念.它适用于所有主要的编程语言.在本章中,我们将尝试在Java语言的上下文中理解此概念.在本章的最后,我们 ...

  9. java 清单文件 生成,使用批处理文件生成文件列表清单

    使用批处理文件生成文件列表清单 使用批处理文件生成文件列表清单,友友们都会遇到这样的情况:想要复制一个文件夹下所有文件的名字,或者将所有文件的名字列出一个清单,用手工复制的话吃力不讨好还容易出差错. ...

最新文章

  1. 独立重复实验与二项分布
  2. Hadoop大数据零基础高端实战培训系列配文本挖掘项目
  3. 机器学习 集成学习篇——python实现Bagging和AdaBOOST算法
  4. 日常生活小技巧 -- vmware workstation 无法连接到虚拟机
  5. 核心期刊 CA JST CSCD 含金量_期刊评介|《仪表技术与传感器》科技期刊的阿玛尼,只管投就对了!...
  6. 《穿越火线:枪战王者》手游客户端技术方案: 实时同步与手感优化
  7. SPOJ - DISUBSTR Distinct Substrings(后缀数组)
  8. AS 自定义 Gradle plugin 插件 案例 MD
  9. OpenCV--常见图片格式转换与深浅拷贝
  10. 在Eclipse上安装pydev开发工具
  11. VB 删除带子文件夹和文件的文件夹
  12. Java中类与对象的定义与使用
  13. 网页保存到mysql数据库_把网页数据保存到数据库
  14. 婚纱摄影、影楼、照相馆流量制造工具预约系统之种草社区
  15. SpringMVC单文件上传、多文件上传、文件列表显示、文件下载
  16. 腾讯2018秋招笔试真题(1)
  17. 剑指offer刷题总记——Java
  18. 直播电商的运营逻辑,是否可以复制?
  19. 【毕业设计】4-基于单片机的锅炉控制系统的研究与设计(原理图+源代码+仿真工程+答辩论文+答辩PPT)
  20. 如何搞好公司和员工的关系一:不要试图和下属做朋友

热门文章

  1. matlab amd补丁,Matlab升级 AMD锐龙性能恢复满血:轻松提升60%
  2. pojo 带参构造函数_带有Java Pojo作为输入输出示例的AWS Lambda函数
  3. openjdk-7支持版本_长期支持对OpenJDK意味着什么?
  4. openapi_MicroProfile OpenAPI上的Swagger UI
  5. monolith_将Java EE Monolith雕刻成微服务
  6. 性能测试流程_流性能
  7. 只针对异常的情况才使用异常_如何以及何时使用异常
  8. 改变数据类型的装饰器_用装饰器改变收藏
  9. java 解析日期格式_日期/时间格式/解析,Java 8样式
  10. 2019年用于自动化的5个最佳Java测试框架