您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 >
Rope:理論與實踐
作者:網絡轉載 發(fā)布時間:[ 2013/3/4 15:49:37 ] 推薦標簽:

為了改進這種情況,Matcher應該而且能夠利用 Rope迭代器提供的更快的 O(1)訪問時間。為了掌握這種方法,首先需要理解 Matcher到其 CharSequence的訪問模式。

正則表達式匹配常見的場景是從字符序列的某個點上開始,向前移動,直到找到所有匹配,并到達序列末尾為止。在這個場景中,匹配器主要是向前移動,一次通常移動不止一個字符。但在少數情況下,匹配器被迫向后移動。

很容易能將 Rope迭代器改成一次向前移動不止一個字符。但是向后移動要復雜些,因為迭代器內部執(zhí)行的是深度優(yōu)先算法,預先排好了 Rope遍歷的順序,需要訪問每個葉節(jié)點。遍歷堆棧沒有足夠的信息能夠前移到前一個葉節(jié)點,但是如果促使向后移動的信息量沒有使迭代器離開當前葉節(jié)點,那么迭代器有可能服務請求。為了說明這個作法,圖 5 顯示一個虛構的迭代器的狀態(tài),它能夠向后移動一、二、三、四個位置,但不能移動更多位置,因為這要求訪問前面訪問的葉節(jié)點。

為了支持這一新功能,可以修改 Rope的 charAt方法,這樣在第一次調用的時候,在指定位置上構建一個迭代器。后續(xù)的調用會將迭代器前后移動指定的距離。如果迭代器不能后移指定的距離,那么執(zhí)行默認的 charAt例程取得字符的值 —這種情況很少發(fā)生。

因為這種優(yōu)化無法做到普遍適用,而且要求引入新的成員變量,所以好不要直接將它添加到 Rope類。相反,可以根據需要用這個優(yōu)化修飾 rope。為此,Ropes for Java 在 Rope類中包含了一個方法,能夠為指定的模式生成優(yōu)化的匹配器。清單 5 演示了這種方法:


清單 5. 優(yōu)化的正則表達式匹配
    
 Pattern p = ...
 Matcher m = rope.matcher(p);

清單 5 中第二行調用對 rope 進行修飾,優(yōu)化正則表達式匹配。

表 7 提供了這種方法的測評結果,并包含了以前的結果(表 6)以便進行對照。

 

技術 時間(單位:納秒)
String 75,286,078
StringBuffer 86,083,830
Rope 12,507,367,218
重新均衡后的 Rope 2,628,889,679
Rope.matcher 246,633,828

優(yōu)化的結果比起重新均衡后的 rope 明顯提高了 10.6 倍,使 rope 的性能與 String性能的差距縮小到 3.2 倍之內。

應用程序

什么時候不應使用 rope企業(yè)級 Java 應用程序經常包含類似下面的代碼:

String x = "<input type='text' name='name' value='"
+ escapePcData(bean.getName()) + "'>";


x 隨后放在 HTML 內發(fā)送到客戶機瀏覽器。用 rope 代替編譯器默認生成的 StringBuilder來計算 x 的值是否有意義?

回答是否,原因有幾個。首先,這里要連接的數據的數量比較小,所以使用 rope 不會提高性能(雖然能夠提高健壯性和伸縮性)。(請設想一下 getName出人意料地返回 50 MB 字符串時這兩種解決方案會如何反應。)

但是出于討論的目的,假設有許多塊數據進行連接。由于 Rope的附加性能通常比 StringBuffer好,這時使用 rope 是否有意義呢?答案還是否。不論何時將輸入的數據組合在一起形成格式化輸出時,漂亮有效的方法是使用模板引擎(例如 StringTemplate 或 FreeMarker)。這種方法不僅能干凈地將表示標記與代碼分開,而且模板只進行一次編譯(通常編譯為 JVM 字節(jié)碼),以后可以重用,從而使它們擁有的性能特征。

使用模板的第二個好處暴露了對于類似以上代碼中那些輸出構建例程(包括用 rope 編寫的例程)常見的基本缺陷。這個好處是:可以對模板進行逐步評估,而且輸出一旦生成可以寫入 Writer,不必先在內存中累積。在 Java EE 應用程序中,Writer實際是到客戶機瀏覽器的緩沖的連接,這種輸出方法呈現恒定的內存量 —— O(1),而其他解決方案的內存使用則是 O(n)。這對應用程序的可伸縮性和健壯性都是 巨大的改進,雖然對小的輸出或較低的應用程序負載來說不是那么明顯。(請參閱 參考資料中兩篇關于流式架構的文章的鏈接,獲得進一步解釋和定量分析。)
.現在對于 rope 的性能已經有了很好的理解,可以考慮 rope 的一些傳統(tǒng)用法,以及在 Java EE 應用程序中吸引人但很可能 并不恰當的用法。

雖然 rope 可以作為一種通用方法替代字符串的連續(xù)內存表示法,但是只有在大量修改大型字符串的應用程序中才能看到明顯的性能提升。這可能并不讓人驚訝,因為早的 rope 應用程序是用來在文本編輯器中表示文檔。不僅在特大的文檔中能夠以幾乎恒定的時間執(zhí)行文本插入和刪除,rope 的不可修改性還使得 “撤消堆棧(undo stack)” 的實現非常容易:只要在每次修改時保存對前一個 rope 的引用即可。

另一個更加神奇的 rope 應用是表示虛擬機的狀態(tài)。例如,ICFP 2007 編程競賽中有一個比賽是實現一個虛擬機,要求每個周期都修改它的狀態(tài),并針對某些輸入運行數百萬個周期(請參閱 參考資料)。在一個 Java 實現中,虛擬機的速度提高了三個數量級,從 ~50 周期 / 秒提高到超過 50,000/ 秒,這是通過使用 Rope代替專門的 StringBuffer來表示狀態(tài)而做到的。

未來的研究方向

雖然 Ropes for Java 是一種新庫,但底層概念并不新鮮,該庫看起來實現了 rope 的性能許諾。但是,該項目希望通過以下方面在未來的發(fā)行版中對庫的某些方面進行改進:

•提供其他常見字符串操作的高性能實現。


•編寫適配器,將 rope 無縫地集成到 Scala和面向 Java 平臺的其他高級語言。


•通過進一步的自動測試提高質量。Ropes for Java 既使用手工編寫的 JUnit 自動測試進行了測試,也通過 JUnit 工廠自動生成的測試進行了測試。集成 ESC/Java 2檢驗過的 Java 建模語言(JML)標注可能會進一步提高質量。

上一頁1234下一頁
軟件測試工具 | 聯系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網站地圖
滬ICP備07036474 2003-2017 版權所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd