第八章第三节 代码调优的设计模式和I/O
本节学习如何经过对代码的修改,消除性能瓶颈,提升系统性能?——代码调优、面向性 能的设计模式html
Outline
- Java调优
- 代码调优的概念
- 单例模式(Singleton Pattern)
- 享元模式(Flyweight Pattern)
- 原型模式(Prototype Pattern)
- 对象池模式(Object Pool Pattern)
- 常见的Java I/O方法
Notes
## 代码调优
【代码调优的概念】java
- 代码调优:代码调优不是为了修复bug,而是对正确的代码进行修改以提升其性能,其经常是小规模的变化
- 调优不会减小代码行数
- 不要猜缘由,而应有明确的优化目标
- 不要边写程序边调优
- 不是性能优化的第一选择
- 代码行数与性能之间无必然的联系
- 代码调优创建在对程序性能的精确度量基础之上(profiling)
- 当程序作过某些调整以后,要从新profiling并从新了解须要优化的性能瓶颈,微小的变化能致使优化方向大不相同
- 性能从不是追求的第一目标,正确性比性能更重要
【单例模式(Singleton Pattern)】设计模式
- 定义:某些类在应用运行期间只须要一个实例。
- 现状:某些类在运行时只要须要一个实例就new,致使不少状况下建立多个object。
- 更好的选择:强制client只能建立一个object实例,避免由于new操做所带来的时空性能(尤为是GC)的损失,也便于复用。
- 优势: 一、在内存里只有一个实例,减小了内存的开销,尤为是频繁的建立和销毁实例(好比管理学院首页页面缓存)。 二、避免对资源的多重占用(好比写文件操做)。
- 缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
- 实现:
- 对重构的代码进行封装,只提供一个访问点
- 提供static的方法容许指定调用
- 模式图:

- 注意:
- 1. 只建立一个实例,而且只提供一个全局的访问点;避免建立多个实例的可能。
- 2. 资源共享状况下,获取实例的方法必须适应多线程并发访问。
- 3. 提升访问性能。
- 4. 懒加载(Lazy Load),在须要的时候才被构造。

【享元模型(Flyweight Pattern)】数组
- 使用场景: 一、系统有大量类似对象。 二、须要缓冲池的场景。
- 特色:该模式容许在应用 中不一样部分共享使用objects,下降大量objects带来的时空代价
- 对象的内部状态:无论在什么场合使用该object,内部特征都不变。
- 对象的外部状态:不是固定的,须要在不一样场合context分别指派/计算其值。
- 实现:
- flyweight声明一个接口来接受外部状态并采起行动
- ConcreteFlyweight保存可共享状态,UnsharedConcreteFlyweight不可共享
- FlyweightFactory负责flyweight的建立、管理、提供给客户端
- 客户端经过索引获取flyweight对象,调用方法计算外在状态
- 优势:大大减小对象的建立,下降系统的内存,使效率提升。
- 缺点:提升了系统的复杂度,须要分离出外部状态和内部状态,并且外部状态具备固有化的性质,不该该随着内部状态的变化而变化,不然会形成系统的混乱
- 模式图:

【原型模式(Prototype Pattern)】缓存
【对象池模式(Object Pool Pattern)】性能优化
## 常见Java I/O

具体请移步 Java I/O 总结多线程
- Java中I/O操做主要是指使用Java进行输入,输出操做. Java全部的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。
- 虽然java IO类库庞大,但整体来讲其框架仍是很清楚的。从是读媒介仍是写媒介的维度看,Java IO能够分为:
- 输入流:InputStream和Reader
- 输出流:OutputStream和Writer
- 而从其处理流的类型的维度上看,Java IO又能够分为:
- 字节流:InputStream和OutputStream
- 字符流:Reader和Writer
- 下面这幅图就清晰的描述了JavaIO的分类:
- |
字节流 |
字符流 |
输入流 |
InputStream |
Reader |
输出流 |
OutputStream |
Writer |

① InputStream/Reader
InputStream/Reader 是输入流,这里的输入输出是相对于内存来讲的。这两个类都是基类(抽象类),不能实例化对象,能够靠它的派生类来实例化对象,实现文件的各类操做。InputStream 是字节流,Reader 是字符流。并发
② OutputStream/Writer
OutputStream/Writer 是输出流,这里是指输出到磁盘等存储介质上,这两个类也都是基类,能够用它们的派生类来实现各类操做。OutputStream 是字节流,Writer 是字符流。框架
【如何选择I/O流】性能
- 肯定是输入仍是输出
- 输入:输入流 InputStream Reader
- 输出:输出流 OutputStream Writer
- 明确操做的数据对象是不是纯文本
- 是:字符流 Reader,Writer
- 否:字节流 InputStream,OutputStream
- 明确具体的设备。
- 文件:
读:FileInputStream,, FileReader,
写:FileOutputStream,FileWriter
- 数组:
byte[ ]:ByteArrayInputStream, ByteArrayOutputStream
char[ ]:CharArrayReader, CharArrayWriter
- String:
StringBufferInputStream(已过期,由于其只能用于String的每一个字符都是8位的字符串), StringReader, StringWriter
- Socket流
键盘:用System.in(是一个InputStream对象)读取,用System.out(是一个OutoutStream对象)打印
- 是否须要转换流
- 是,就使用转换流,从Stream转化为Reader、Writer:
- InputStreamReader,OutputStreamWriter
- 是否须要缓冲提升效率
- 是就加上Buffered:BufferedInputStream, BufferedOuputStream, BufferedReader, BufferedWriter
- 是否须要格式化输出