- 浏览: 568666 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
fiwrc:
知道了. 谢谢~!
\(^_^)/ Java多线程Master-Worker模式 -
fiwrc:
求问 getResultMap 是什么方法???? .. ...
\(^_^)/ Java多线程Master-Worker模式 -
我改名了:
...
\(^_^)/ 表达式解析器(MVEL) -
拓子轩:
赞一个
Oracle 语句大全 -
rudaoxia:
写的很详细,很好,还有很多的拓展,谢谢博主,收下了
\(^_^)/ JDK工具、命令
自从第一个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 */
}
为了简单起见,我将只贴出写入方法(尽管读取类似),完整的源码在我的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框架,新旧版本的差距是很大的,我做过测试。因为性能比较上并没有体现出特别引人注意的差异,所以我将使用2.x版本,因为它对用户更友好而且更快些。
private static Kryo kryo = new Kryo(); // version 2.x
public 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的文章中提到的(Native C/C++ Like Performance For Java Object Serialisation),介绍了怎样在Java中像C++那样和内存打交道。
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 nulls
boolean 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 reflection
public 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 */
}
几个小时的Caliper测试结果如下:
Full trip [ns] Standard deviation [ns]
Standard 207307 2362
Standard on RAF 42661 733
KRYO 1.x 12027 112
KRYO 2.x 11479 259
Unsafe 8554 91
在最后我们可以得出一些结论:
•Unsafe序列化比标准的java.io.Serizlizable快了23倍
•使用RandomAccessFile可以使标准的有缓冲序列化加速将近4倍
•Kryo-dynamic序列化大约比手写实现的直接缓冲满了35%
最后,就像我们看到的那样,还是没有绝对的答案。对于我们中的大多数人来说,获得3000ns(0.003ms)的速度提升是不值得为每个需要序列化的对象来写单独实现的。在标准的方案中,我们大多数选择Kryo 。然而,在惜时如金的低延时系统中,这个选择将会是完全不同的。
转载
发表评论
-
Java 设计模式和设计原则
2017-12-22 15:00 0http://java-design-patterns.c ... -
jeesite,jeeplus,jeecg,jfinal
2017-12-21 19:43 0jeesite,jeeplus,jeecg,jfinalh ... -
batch scheduler
2017-08-10 18:19 0batch scheduler -
statsd+graphite+grafana 监控
2016-09-27 14:58 0https://my.oschina.net/u/138210 ... -
spring boot admin server
2016-09-02 17:17 0关键词:Spring boot 监控、Spring Boo ... -
资料备份
2016-07-22 17:29 0微服务 -
spring cloud
2016-07-17 22:03 0spring cloud http://blog. ... -
oschina_git_java 开源项目
2016-04-22 17:21 0项目 描述 JFinal / JFinal ... -
Mybatis Generator 配置文件
2016-04-08 15:44 693<?xml version="1.0&quo ... -
Java中的Object类
2015-08-03 09:53 662package java.lang; ... -
\(^_^)/ Java 反射
2015-05-17 15:49 1125http://blog.csdn.net/libo2006 ... -
Maven中的pom.xml文件
2015-05-14 23:01 12003http://blog.csdn.net/adeyi/ar ... -
Eclipse中的.project文件、classpath文件
2015-05-14 22:58 2902<?xml version="1.0&qu ... -
eclipse中的.classpath文件
2015-05-14 22:40 102.classpath的位置定义了你这个项目在编译时所使用的 ... -
TreadLocal xxx
2015-04-09 23:06 0ThreadLocal是什么 早在JD ... -
\(^_^)/ Servlet、Filter、Listener、Interceptor
2015-01-13 15:49 1338参考:http://thinkerandthinker.i ... -
\(^_^)/ 表达式解析器(MVEL)
2014-10-21 22:08 12219Jeval 在运行时解析计算静态和动态表达式;支持数学, ... -
\(^_^)/ POI读写海量Excel
2014-10-13 19:50 2552转自:http://blog.csdn.net/goodku ... -
\(^_^)/ Java8 源码目录结构
2014-06-27 22:45 631├─com │ └─sun ... -
\(^_^)/ eclipse 插件、注释模版、配置
2014-06-06 15:53 3235Eclipse 插件 1. Fi ...
相关推荐
以下是一些加快Java文件序列化速度的方法: 1. **优化对象结构**: - **减少嵌套深度**:如果对象层次太深,序列化和反序列化时会增加额外的时间开销。尽量简化对象结构,避免过多的嵌套。 - **精简对象属性**:...
它们允许序列化和反序列化Java对象,使得对象能在网络间传输。 5. **NIO(New Input/Output)**: Java NIO(非阻塞I/O)提供了一种新的方式来处理I/O操作,尤其是对于高并发的网络应用。它使用Channel和Selector...
MessagePack就是一种高效、跨语言的数据序列化库,它专为速度和效率而设计,特别适合处理大数据量的场景。 **MessagePack简介** MessagePack是一种轻量级的二进制序列化格式,它的目标是比JSON更快、更小。在保持...
protoc jar文件用于编译.proto文件,将定义的协议消息类型转换为Java类,而Java运行时库则是在应用程序中处理序列化和反序列化的必要依赖。 在Android开发中,protobuf被广泛应用于服务器与客户端之间的数据交换,...
从LCD到RDF 将ILCD XML序列化中的LCA数据转换为(大致等效)RDF / XML序列化ILCD模式非常大,此代码仅转换很小的子集,足以表示进程及其输入和输出流。 这样做的主要动机是探索关联数据和LCA的机会和问题。依存关系...
3. **FastJson**:FastJson是阿里巴巴开源的一款高性能的JSON库,用于JSON的序列化和反序列化。在爬虫项目中,FastJson可以帮助将抓取到的JSON格式数据快速转换为Java对象,便于存储和后续处理。同时,它也能将Java...
- 序列化:默认情况下,spymemcached使用Java序列化。但你可以自定义序列化策略,比如使用Gson或Jackson库进行JSON序列化,以提高性能和可读性。 - 批量操作:支持批量设置、获取和删除键值对,减少网络往返次数,...
Java的序列化、Base64编码或自定义的打包格式都可以用于此目的。 5. **异常处理**:在文件传输过程中可能出现各种错误,如网络中断、文件不存在等,因此需要适当的异常处理机制。 6. **状态同步**:多线程环境下,...
- 使用Java的`ObjectOutputStream`和`ObjectInputStream`类可以序列化和反序列化对象,将棋盘状态保存到文件中,然后在需要时读取。保存时,将棋盘、棋子、玩家等核心对象写入文件;加载时,从文件读取这些信息恢复...
7. **配置灵活**:OSCache的配置文件(如`etc/oscache.properties`)允许开发者自定义缓存设置,如缓存大小、过期策略、序列化方式等。 8. **文档齐全**:提供的`docs`目录包含了详细的用户指南和技术参考,方便...
Java 实现百度搜索框自动补全是一个常见的前端与...总的来说,Java实现的百度搜索框自动补全涉及到前端与后端的协同工作,包括Ajax通信、数据库操作和数据序列化。这个小demo提供了一个学习和实践这些技术的好机会。
2. **编译器**:`protoc`是Protocol Buffer提供的编译器,它可以将.proto文件编译成不同编程语言(如C++、Java、Python等)的源代码,生成的类库提供了序列化和反序列化的接口。 3. **序列化与反序列化**:Protocol...
5. **配置与使用**:使用 memcached-session-manager 需要在Web应用的配置文件中指定相关参数,如 Memcached 服务器的地址、端口,以及是否启用 Kryo 序列化等。开发者还需要在代码中适当地创建和管理会话。 6. **...
Ehcache是一个高性能、轻量级的Java分布式缓存库,它被广泛应用于提升应用程序的性能,通过存储经常访问的数据来减少对数据库的依赖,从而加快系统的响应速度。本入门案例将带你了解如何使用Ehcache实现分布式缓存,...
开发者可以使用protobuf编译器将.proto文件转换为目标语言(如C++、Java、Python等)的源代码,生成的类库提供了序列化和反序列化的API,使得数据可以在不同系统之间进行高效通信。 在“protobuf-all-3.6.1.zip”这...
然而,Netty允许开发者直接传输Java对象,这是通过序列化和反序列化机制实现的。Netty提供了`ObjectEncoder`和`ObjectDecoder`这两个编解码器,它们负责将Java对象转换为字节流,以便在网络上传输,到达目的地后再...
用户可能希望继续他们之前的游戏,这就需要用到文件操作和序列化技术,将游戏状态保存到硬盘上,然后在下次启动时恢复。 总的来说,这个基于Java的俄罗斯方块项目展示了Java GUI编程、对象设计、事件处理、算法实现...
- **存储优化**:在数据库或文件系统中,protobuf序列化的数据可以减少存储空间,加快读写速度。 5. **优势与局限**: - **优点**:效率高,占用空间小,支持多种语言,易于扩展和维护。 - **局限**:学习曲线较...
通过这样的方式,我们可以编写Java代码来实现协议缓冲区的高效序列化和反序列化,然后在Matlab中调用这些Java方法,从而提升处理速度。 具体步骤可能包括以下几点: 1. **设计Java接口**:首先,我们需要设计一个...