通过快速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的第一个版本开始,许多开发人员每天都在努力实现至少与C / C ++一样好的性能. JVM供应商正在通过实现一些新的JIT算法来尽力而为,但仍有许多工作要做,尤其是在我们 ...
- ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler
ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler, 使用<link type="text/css" rel="Stylesheet" ...
- java文件复制速度_java中文件复制得速度测试
//需要将apache开发的两个插件包拷到lib目录下:commons-fileupload-1.2.2.jar commons-io-2.0.1.jar package com.nay.servl ...
- linux rsync删文件速度,Linux下使用rsync最快速删除大量文件的方法
要在Linux下删除海量文件的情况,需要删除三层哈希目录下的几十万个文件.这个时候,删除命令rm -rf * 就不好用了,因为要等待的时间太长.所以必须要采取一些非常手段.我们可以使用rsync来实现 ...
- win11如何加快搜索速度 Windows11更改文件索引加快搜索速度的设置方法
有时候当你急需寻找一份文件的时候,可能查找筛选需要很长时间,但是有什么方法可以加快寻找文件的搜索速度呢?今天小编就为大家带来更改文件索引加快搜索速度的教程.更多Windows11安装步骤可以参考小白一 ...
- java之文件与IO流及序列化
目录 文件 java操作文件原理 File类 封装文件为File类对象 常用文件方法 File对象对文件进行操作 File对象对目录进行操作 IO流 IO流的分类 节点流与处理流 处理流特点 字节流与 ...
- Java对象XML序列化框架-Simple2.0
Java对象XML序列化框架-Simple2.0 Simple是一个XML序列化框架,一个Java 版本宽容的序列化框架,能够快速在Java 平台上开发XML.支持通过annotations完全配置化 ...
- fileinputstream自定义类序列化和反序列化_Rest Assured篇:Java中的序列化和反序列化...
点击上方蓝字设为星标 每天傍晚伴你一起成长! Java 中的序列化和反序列化是一个重要的编程概念.它适用于所有主要的编程语言.在本章中,我们将尝试在Java语言的上下文中理解此概念.在本章的最后,我们 ...
- java 清单文件 生成,使用批处理文件生成文件列表清单
使用批处理文件生成文件列表清单 使用批处理文件生成文件列表清单,友友们都会遇到这样的情况:想要复制一个文件夹下所有文件的名字,或者将所有文件的名字列出一个清单,用手工复制的话吃力不讨好还容易出差错. ...
最新文章
- 独立重复实验与二项分布
- Hadoop大数据零基础高端实战培训系列配文本挖掘项目
- 机器学习 集成学习篇——python实现Bagging和AdaBOOST算法
- 日常生活小技巧 -- vmware workstation 无法连接到虚拟机
- 核心期刊 CA JST CSCD 含金量_期刊评介|《仪表技术与传感器》科技期刊的阿玛尼,只管投就对了!...
- 《穿越火线:枪战王者》手游客户端技术方案: 实时同步与手感优化
- SPOJ - DISUBSTR Distinct Substrings(后缀数组)
- AS 自定义 Gradle plugin 插件 案例 MD
- OpenCV--常见图片格式转换与深浅拷贝
- 在Eclipse上安装pydev开发工具
- VB 删除带子文件夹和文件的文件夹
- Java中类与对象的定义与使用
- 网页保存到mysql数据库_把网页数据保存到数据库
- 婚纱摄影、影楼、照相馆流量制造工具预约系统之种草社区
- SpringMVC单文件上传、多文件上传、文件列表显示、文件下载
- 腾讯2018秋招笔试真题(1)
- 剑指offer刷题总记——Java
- 直播电商的运营逻辑,是否可以复制?
- 【毕业设计】4-基于单片机的锅炉控制系统的研究与设计(原理图+源代码+仿真工程+答辩论文+答辩PPT)
- 如何搞好公司和员工的关系一:不要试图和下属做朋友
热门文章
- matlab amd补丁,Matlab升级 AMD锐龙性能恢复满血:轻松提升60%
- pojo 带参构造函数_带有Java Pojo作为输入输出示例的AWS Lambda函数
- openjdk-7支持版本_长期支持对OpenJDK意味着什么?
- openapi_MicroProfile OpenAPI上的Swagger UI
- monolith_将Java EE Monolith雕刻成微服务
- 性能测试流程_流性能
- 只针对异常的情况才使用异常_如何以及何时使用异常
- 改变数据类型的装饰器_用装饰器改变收藏
- java 解析日期格式_日期/时间格式/解析,Java 8样式
- 2019年用于自动化的5个最佳Java测试框架