第八章第三節 代碼調優的設計模式和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
- 是否須要格式化輸出