热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

序列化和性能

转载自http:www.360doc.comcontent0612170015643_296709.shtml通常人们认识的序列化类实现java.io.Serializable

转载自http://www.360doc.com/content/06/1217/00/15643_296709.shtml

通常人们认识的序列化类实现java.io.Serializable 像这样:


import java.io.*;

public class Pojo implements Serializable {

private static final long serialVersiOnUID= L;

....

}

这种做法被广大程序员广泛应用,然而这种序列化的性能很低。它使用反射机制寻找序列化类的类变量和这些类变量的类型。大家都知道反射是一个非常消耗时间的处理过程。

我们如何能尽可能的在程序中减轻这种负载呢?有下面三种方法:

1.使用ObjectStreamField类
2.使用readObject / writeObject
方法
3.使用Externalizable 接口

在上面的方法中,性能最好的是使用Externalizable 接口。为了便于理解,将为不同的方法例举一个例子。

ObjectStreamField
类为序列化机制提供序列化对象的成员变量以及成员变量的类型。这样做的好是可以节约一部分时间,他不必通过反射机制去查询成员变量以及类型。关键字transient
仍然可以在这种方式下正常使用,不过在创建ObjectStreamField对象添加序列话成员变量的时候,剔除transient 标识的成员变量。

public class Pojo implements Serializable {

private static final long serialVersiOnUID= 1L;

private String valueA = "SomeTextA";
private int valueB = 10;
private
float valueC = 100f;
private double valueD = 100.100d;
private short
valueE = 10;

// Getters and setters go here.

private static final ObjectStreamField[] serialPersistFields = {
new
ObjectStreamField("valueA", String.class),
new ObjectStreamField("valueB",
Integer.class),
new ObjectStreamField("valueC", Float.class),
new
ObjectStreamField("valueD", Double.class),
new ObjectStreamField("valueE",
Short.class)
};
}

就像你所看到的,为了提升性能得必须指明你所序列化的成员变量,当然除了transient 的成员变量。

第二种方法是使用readObject / writeObject 方法。

public class Pojo implements Serializable {

private static final long serialVersiOnUID= 1L;

private String valueA = "SomeTextA";
private int valueB = 10;
private
float valueC = 100f;
private double valueD = 100.100d;
private short
valueE = 10;

// Getters and setters go here.

private void writeObject(ObjectOutputStream oos) throws IOException {

oos.writeUTF(valueA);
oos.writeInt(valueB);
oos.writeFloat(valueC);

oos.writeDouble(valueD);
oos.writeShort(valueE);
}

private void readObject(ObjectInputStream ois) throws IOException,
ClassNotFoundException {
this.valueA = ois.readUTF();
this.valueB =
ois.readInt();
this.valueC = ois.readFloat();
this.valueD=
ois.readDouble();
this.valueE= ois.readShort();
}
}


这种方式包括了序列化的序列化和反序列化过程。就像上面所展示的,仍然需要声明Serializable 接口。

第三种方式使用Externalizable 接口。

public class Pojo implements Externalizable {

private static final long serialVersiOnUID= 1L;

private String valueA = "SomeTextA";
private int valueB = 10;
private
float valueC = 100f;
private double valueD = 100.100d;
private short
valueE = 10;

// Getters and setters go here.

public void writeExternal(ObjectOutput out) throws IOException {

out.writeUTF(valueA);
out.writeInt(valueB);
out.writeFloat(valueC);

out.writeDouble(valueD);
out.writeShort(valueE);
}

public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
this.valueA = in.readUTF();
this.valueB =
in.readInt();
this.valueC = in.readFloat();
this.valueD=
in.readDouble();
this.valueE= in.readShort();
}
}


这种方式与readObject / writeObject 方式不同的是不再需要声明Serializable 接口, readObject /
writeObject 方法使用ObjectOutput/ObjectInput 接口作为参数代理输入流输出流实现类,并且serialVersionUID
仍然可以使用。

下面将测试各种序列化方法所消耗的时间:

public class Run {

private static int TIMES = 500000;

public static void main(String[] args) {
Pojo sp = new Pojo();

long start = System.currentTimeMillis();
for (int i = 0;
iserialize(sp);
}
long duration =
System.currentTimeMillis() - start;

System.out.println("Externalizable: " + duration + "ms.");
}

public static void serialize(Pojo o) {
try {
ByteArrayOutputStream
bout = new ByteArrayOutputStream();
ObjectOutputStream out = new
ObjectOutputStream(bout);
out.writeObject(o);
out.close();
} catch
(Exception e) {
e.printStackTrace();
}
}

}


为了获得正确的测试结果,我们制定以下规则
。首先,不能测试一小部分对象,应该取较大的均值。第二,减小不必要的负载。如果测试程序快速产生大量的对象,会产生大量的垃圾收集。

在上面的代码中,我们仅序列化了50000个对象。并且没有将序列化的内容写入磁盘或者网络,因为会产生我们不希望的负载。

还有一点值得注意的是,如果有多个String类型的成员变量,他们之应该是不同的值。如果他们的值相同,那么他们引用的是同一个对象。

下面是不同jdk版本间的测试结果:

JDK 1.4.2_12

Serializable: 9766ms.
Streamfield: 9656ms.
Read/Write object: 7781ms.

Externalizable: 5875ms.


JDK 1.5.0_19

Serializable: 9016ms.
Streamfield: 8859ms.
Read/Write object: 7141ms.

Externalizable: 5610ms.

JDK 1.6.0 (B103)

Serializable: 7484ms.
Streamfield: 7312ms.
Read/Write object: 5610ms.

Externalizable: 4828ms.

有趣的是你可以发现使用Externalizable
接口提升了55%的性能。同时也可以看出jdk不同版本的垃圾收集器&Hotpot引擎性能也在提升

序列化和性能,布布扣,bubuko.com


推荐阅读
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • 自动验证时页面显示问题的解决方法
    在使用自动验证功能时,页面未能正确显示错误信息。通过使用 `dump($info->getError())` 可以帮助诊断和解决问题。 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 本文介绍了如何使用 CMD 批处理脚本进行文件操作,包括将指定目录下的 PHP 文件重命名为 HTML 文件,并将这些文件复制到另一个目录。 ... [详细]
  • 本文详细介绍了DMA控制器如何通过映射表处理来自外设的请求,包括映射表的设计和实现方法。 ... [详细]
  • Spark中使用map或flatMap将DataSet[A]转换为DataSet[B]时Schema变为Binary的问题及解决方案
    本文探讨了在使用Spark的map或flatMap算子将一个数据集转换为另一个数据集时,遇到的Schema变为Binary的问题,并提供了详细的解决方案。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 两个条件,组合控制#if($query_string~*modviewthread&t(&extra(.*)))?$)#{#set$itid$1;#rewrite^ ... [详细]
  • 解决Win10下MySQL连接问题:Navicat 2003无法连接到本地MySQL服务器(10061)
    本文介绍如何在Windows 10环境下解决Navicat 2003无法连接到本地MySQL服务器的问题,包括启动MySQL服务和检查配置文件的方法。 ... [详细]
  • 本文详细介绍了如何利用Duilib界面库开发窗体动画效果,包括基本思路和技术细节。这些方法不仅适用于Duilib,还可以扩展到其他类似的界面开发工具。 ... [详细]
  • 解决Parallels Desktop错误15265的方法
    本文详细介绍了在使用Parallels Desktop时遇到错误15265的多种解决方案,包括检查网络连接、关闭代理服务器和修改主机文件等步骤。 ... [详细]
author-avatar
有你真好-LOVE
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有