作者
為性能而設計
[b]學習怎樣在設計 Java 類的時候避免性能冒險
[b][u]概述[/u][/b]
許多 Java 的通常性能問題來源於設計過程早期的類設計想法中
性能問題之前
釋了怎樣在設計時間避免它們
問題
By Brian Goetz
翻譯 by SuperMMX
這個系列探索一些早期的設計思想對應用程序的性能產生影響的方法
一個類的對象創建行為是如何嵌入它的接口中的
對象
程序來說是一個性能指標
這是值得的
在第一和第二部分我集中於對象的創建
但是
的性能問題就在眼前了
單地檢查一個類的接口來預測到分布式應用程序中的性能問題
閱讀這個
第一部分: 接口事宜
第二部分: 減少對象創建
第三部分: 遠程接口
[b][u]遠程調用的概觀[/u][/b]
在分布式的應用程序中
的方法
你首先要找到它
命名服務
當你通過目錄服務得到一個遠程對象的引用時
是一個實現了和遠程對象同樣接口的stub對象的引用
對象把方法的所有參數匯集起來
過程
你想調用的實際的對象的方法
起來
調用要做這麼多的工作
更大
以上描述浏覽了一些對於程序性能非常重要的細節
而是一個對象時
它就創建一個中stub對象和一個skeleton對象
這顯然是一個高代價的操作
參與的 JVM 維護一個線程來和其他 JVM 的維護線程進行通訊
返回的對象不支持遠程調用
代價的操作
[b][u]遠程和本地方法調用的性能比較[/u][/b]
遠程對象訪問的性能特征和本地的不一樣:
遠程對象的創建比本地對象創建代價要高
和skeleton對象也要創建
遠程方法調用還包括網絡的傳遞
匯集起來
調用所導致的延遲都加在一起; 客戶端通常是等待所有這些而步驟完成
大地依賴於底層網絡的延時
不同的數據類型有不同的匯集開支
Point 或者 String 要多一些; 匯集遠程對象要多得多
對象(象 collection 等)要更多
一個復雜對象的引用花費多
[b][u]接口設計是關鍵[/u][/b]
設計不好的遠程接口可能完全消除一個程序的性能
的特性對遠程對象可能不適合
也能阻礙分布式的應用程序
時對象(比如一個 Point)中返回多個值的方法比多次調用來分別得到它們可能更有效
意
[b][u]實際遠程應用程序的一些重要的性能指導:[/u][/b]
提防不必要的數據傳遞
遠程調用中實現可能容易一些
當調用者可能不必要保持一個遠程對象的引用時
當遠程對象不需要一個對象的拷貝時
幸運的是
的方法調用序列可以從類接口中明顯看到
的遠程方法調用
[b][u]減少遠程調用代價的技巧[/u][/b]
一個例子
含了 DirectoryEntry 對象的引用
[code]
public interface Directory extends Remote {
DirectoryEntry[] getEntries();
void addEntry(DirectoryEntry entry);
void removeEntry(DirectoryEntry entry);
}
public interface DirectoryEntry extends Remote {
String getName();
String getPhoneNumber();
String getEmailAddress();
}
[/code]
現在假設你想在一個 GUI email 程序中使用 Directory 的東西
getEntries() 來得到入口的列表
當用戶選擇一個時
在你能夠寫一封 email 之前有多少遠程方法調用必須發生? 你必須調用 getEntries() 一
次
中有 N 個入口
用
口的時候非常慢
問題
現在考慮增強的 Directory 接口:
[code]
public interface Directory extends Remote {
String[] getNames();
DirectoryEntry[] getEntries();
DirectoryEntry getEntryByName(String name);
void addEntry(DirectoryEntry entry);
void removeEntry(DirectoryEntry entry);
}
[/code]
這將減少多少你的 email 程序所造成的花費呢? 現在你可以調用 Directory
一次就可以同時得到所有的名字
這個過程需要
如果地址簿有再多一點的名字
大的不同
用來減少遠程調用和引用傳遞的代價的技術叫做使用次要對象標識符
屬性
次要標識符包含了它描述的對象足夠的信息
在這個目錄系統的例子中
安全皮包管理系統
另一個減少遠程調用數量的技巧是塊獲取
次獲取多個需要的 DirectoryEntry 對象:
[code]
public interface Directory extends Remote {
String[] getNames();
DirectoryEntry[] getEntries();
DirectoryEntry getEntryByName(String name);
DirectoryEntry[] getEntriesByName(String names[]);
void addEntry(DirectoryEntry entry);
void removeEntry(DirectoryEntry entry);
}
[/code]
現在你不僅可以得到需要的遠程 DirectoryEntry
要的所有的入口
延遲很重要的話
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27291.html