我最近在Java中發現了「assert」聲明,並且在我調試它時拋棄了我的軟件。我最初的直覺是爲了避免僅僅爲了處理assert語句而製作控制流程語句,但後來我意識到,無論如何,這些控制語句可能會在生產構建過程中被移除,因爲它們的塊將是空的。我的印象是它們將被JIT編譯器消除。圍繞assert語句的迭代器會影響生產構建的性能嗎?
不幸的是,我正在關於JIT編譯器如何工作的模糊回憶,並找不到合適的文檔。我能找到的最好的是IBM的優化過程的brief outline。
在我開始實施基於斷言的測試的習慣之前,我想知道是否有最佳實踐來最大限度地降低其對性能的影響。我討厭實施一系列測試,發現它們的集體效應會大幅降低性能,即使它們的影響可以忽略不計。
您能否告訴我以下幾行是否會影響生產版本的性能(默認情況下「禁用斷言」)?
for (T obj : Collection){
assert obj.someProperty();
}
對於獎金,如果我是更復雜的東西,包括僅用於斷言的短期對象,該怎麼辦?
TreeMap<Integer,T> map = new TreeMap<>();
int i = 0;
for (T obj : Collection){
map.put(i,obj);
assert obj.someProperty();
i++;
}
// assert something about map, then never use it again
還是一種方法,其唯一的效果是調用「斷言」?
在此先感謝!從「assert」語句的Oracle文檔
相關摘錄:
這些討論如何從類文件,這不正是我擔心刪除斷言。
卸下從類文件程序員斷言的所有痕量 用於資源受限設備開發應用程序可能希望 條斷言出類文件的完全。雖然這使得 無法啓用該領域的斷言,但它也減少了文件大小,可能會導致類加載性能的提高。在缺少高質量JIT的情況下,可能會導致減少佔用面積並提高運行時性能。
斷言工具不提供對剝離類文件外的 斷言的直接支持。 assert語句可能,但是,在與「條件編譯」成語結合使用 在Java語言規範描述 ,使編譯器以消除 的這些所有痕跡從它所生成的類文件聲稱:
static final boolean asserts = ...; //假消除斷言
if(assert)assert;
和常見問題解答部分:
爲什麼不提供一個編譯器標誌完全消除目標文件中的斷言 ?這是一個堅定的要求,有可能在現場啓用斷言,以提高可服務性。它可能允許開發者在編譯時從目標文件中刪除斷言 。斷言可以包含邊 的影響,儘管它們不應該,並且這樣的標誌因此可以以顯着的方式改變程序的行爲。它被認爲是好的 事情只有一個語義與每個有效的Java程序相關聯。此外,我們希望鼓勵用戶在對象 文件中保留斷言,以便可以在該字段中啓用它們。最後,規範要求 這個斷言表現得好像在類被初始化之前運行時一樣運行。如果從類文件中剝離了 斷言,將不可能提供這些語義。但是,請注意,可以使用Java 語言規範中描述的標準「條件編譯慣用語」爲 開發人員實現此效果。
我沒有記得足夠的細節給出一個自信的答案,但我認爲斷言啓用/禁用是在運行時,而不是編譯時。 – Brandon
@布蘭登:謝謝你的提高。如果是這樣的話,我想答案是微不足道的。也許我需要讀一些關於「斷言」的內容。我添加了一個問題鏈接... –