java format 补足空格_11个简单的Java性能调优技巧
想要保持程序高效運行?您可以采取一些步驟來消除瓶頸,緩存提示以及其他性能調(diào)整建議。
大多數(shù)開發(fā)人員期望性能優(yōu)化是一個復(fù)雜的主題,需要大量的經(jīng)驗和知識。好的,那不是完全錯誤的。優(yōu)化應(yīng)用程序以獲得最佳性能并非易事。但這并不意味著如果您沒有獲得該知識就不會做任何事情。有一些易于遵循的建議和最佳實踐,可以幫助您創(chuàng)建性能良好的應(yīng)用程序。
這些建議大多數(shù)都是特定于Java的。但是,還有幾種獨立于語言的語言,可以將其應(yīng)用于所有應(yīng)用程序和編程語言。在獲得特定于Java的性能調(diào)優(yōu)技巧之前,讓我們先討論其中的一些通用技巧。
1.在知道必要之前不要進行優(yōu)化
這可能是最重要的性能調(diào)優(yōu)技巧之一。您應(yīng)該遵循常見的最佳做法,并嘗試有效地實現(xiàn)用例。但這并不意味著您在證明有必要之前就應(yīng)該替換任何標準庫或構(gòu)建復(fù)雜的優(yōu)化。
在大多數(shù)情況下,過早的優(yōu)化會占用大量時間,并使代碼難以閱讀和維護。更糟的是,這些優(yōu)化通常不會帶來任何好處,因為您要花費大量時間來優(yōu)化應(yīng)用程序的非關(guān)鍵部分。
那么,如何證明需要優(yōu)化某些東西?
首先,您需要定義應(yīng)用程序代碼的速度,例如,通過指定所有API調(diào)用的最大響應(yīng)時間或要在指定時間范圍內(nèi)導(dǎo)入的記錄數(shù)來定義應(yīng)用程序代碼。完成此操作后,您可以衡量應(yīng)用程序的哪些部分太慢并且需要改進。完成之后,您應(yīng)該看看第二個技巧。
2.使用探查器查找真正的瓶頸
在遵循了第一條建議并確定了需要改進的應(yīng)用程序部分之后,請問自己從哪里開始?
您可以通過兩種方式解決此問題:
· 您可以看一下代碼,從看起來可疑的部分開始,或者在可能會造成問題的地方開始。
· 或者,您使用探查器并獲取有關(guān)代碼各部分的行為和性能的詳細信息。
我希望我不需要解釋為什么您應(yīng)該始終遵循第二種方法。
顯然,基于事件探查器的方法可以使您更好地了解代碼的性能含義,并使您可以專注于最關(guān)鍵的部分。而且,如果您曾經(jīng)使用過探查器,您會記得一些情況,您對代碼的哪些部分造成了性能問題感到驚訝。我的第一次猜測不止一次會把我引向錯誤的方向。
3.為整個應(yīng)用程序創(chuàng)建一個性能測試套件
這是另一個通用技巧,可幫助您避免在將性能改進部署到生產(chǎn)后經(jīng)常發(fā)生的許多意外問題。您應(yīng)該始終定義一個性能測試套件,以測試整個應(yīng)用程序,并在進行性能改進之前和之后運行它。
這些額外的測試運行將幫助您確定所做更改的功能和性能方面的副作用,并確保您不會發(fā)布造成弊大于利的更新。如果您要處理應(yīng)用程序的多個不同部分所使用的組件(例如數(shù)據(jù)庫或緩存),則這一點尤其重要。
4.首先解決最大的瓶頸
創(chuàng)建測試套件并使用事件探查器分析應(yīng)用程序之后,您將獲得要解決的問題列表,以提高性能。很好,但是仍然無法回答應(yīng)該從哪里開始的問題。您可以專注于快速獲勝,或者從最重要的問題開始。
從快速獲勝開始可能會很誘人,因為您很快就可以顯示首個結(jié)果。有時,可能有必要說服其他團隊成員或您的管理層認為進行性能分析是值得的。
但總的來說,我建議從頭開始,并首先著手處理最重要的性能問題。這將為您提供最大的性能改進,并且您可能不需要解決多個問題即可滿足您的性能要求。
足夠了解一般的性能調(diào)優(yōu)技巧。讓我們仔細看看一些特定于Java的代碼。
5.使用StringBuilder以編程方式連接字符串
在Java中,有很多不同的選項來連接String。例如,您可以使用簡單的+或+ =,舊的StringBuffer或StringBuilder。?
那么,您應(yīng)該選擇哪種方法呢?
答案取決于連接String的代碼。如果要以編程方式向String中添加新內(nèi)容,例如在for循環(huán)中,則應(yīng)使用StringBuilder。它比StringBuffer易于使用并提供更好的性能。但是請記住,與StringBuffer相比,StringBuilder不是線程安全的,并且可能不適用于所有用例。
您只需要實例化一個新的StringBuilder并調(diào)用append方法即可將一個新部分添加到String中。添加完所有部分后,可以調(diào)用toString()方法來檢索串聯(lián)的String。
以下代碼片段顯示了一個簡單的示例。在每次迭代期間,此循環(huán)將i轉(zhuǎn)換為String并將其與空格一起添加到StringBuilder sb。因此,最后,此代碼將“ This is a test0 1 2 3 4 5 6 7 8 9”寫入日志文件。
StringBuilder sb = new StringBuilder(“This is a test”);
for (int i=0; i<10; i++) {
sb.append(i);
sb.append(” “);
}
log.info(sb.toString());
如您在代碼片段中所看到的,您可以將String的第一個元素提供給構(gòu)造方法。這將創(chuàng)建一個新的StringBuilder,其中包含提供的String以及16個其他字符的容量。當(dāng)您向StringBuilder添加更多字符時,JVM將動態(tài)增加StringBuilder的大小。
如果您已經(jīng)知道String包含多少個字符,則可以將該數(shù)字提供給不同的構(gòu)造方法,以實例化具有定義容量的StringBuilder。由于它不需要動態(tài)擴展其容量,因此進一步提高了效率。
6.使用+在一個語句中連接字符串
當(dāng)您使用Java實現(xiàn)第一個應(yīng)用程序時,可能有人告訴您,不應(yīng)將String與+串聯(lián)在一起。如果在應(yīng)用程序邏輯中串聯(lián)String,那是正確的。String是不可變的,每個String串聯(lián)的結(jié)果存儲在新的String對象中。這需要額外的內(nèi)存并減慢您的應(yīng)用程序的速度,尤其是當(dāng)您在循環(huán)中串聯(lián)多個String時。
在這些情況下,應(yīng)遵循技巧5并使用StringBuilder。
但是,如果您只是將String分成多行以提高代碼的可讀性,則不是這種情況。
Query q = em.createQuery(“SELECT a.id, a.firstName, a.lastName ”
+ “FROM Author a ”
+ “WHERE a.id = :id”);
在這種情況下,應(yīng)將String與簡單的+串聯(lián)在一起。您的Java編譯器將對此進行優(yōu)化,并在編譯時執(zhí)行串聯(lián)。因此,在運行時,您的代碼將僅使用1 String,并且不需要連接。
7.盡可能使用基元
避免任何開銷并提高應(yīng)用程序性能的另一種快速簡便的方法是使用原始類型而不是其包裝器類。因此,最好使用int而不是Integer,或者使用double而不是Double。這使你的JVM來?的值存儲在堆棧,而不是堆的,以減少內(nèi)存消耗和更有效的整體處理。
8.盡量避免使用BigInteger和BigDecimal
正如我們已經(jīng)在討論數(shù)據(jù)類型一樣,我們還應(yīng)該快速瀏覽一下BigInteger和BigDecimal。尤其是后者由于其精確性而受歡迎。但這是有代價的。??
與簡單的long或double相比,BigInteger和BigDecimal需要更多的內(nèi)存,從而大大降低了所有計算的速度。因此,如果您需要更高的精度,或者您的數(shù)字將超出long的范圍,請三思。這可能是您唯一需要更改以解決性能問題的東西,尤其是在實現(xiàn)數(shù)學(xué)算法的情況下。
9.首先檢查當(dāng)前日志級別
該建議應(yīng)該很明顯,但是不幸的是,您可以找到許多忽略它的代碼。創(chuàng)建調(diào)試消息之前,應(yīng)始終先檢查當(dāng)前日志級別。否則,您可能會使用?日志消息創(chuàng)建一個字符串,該字符串隨后將被忽略。
這是兩個不應(yīng)該這樣做的例子。
// don’t do this
log.debug(“User [” + userName + “] called method X with [” + i + “]”);
// or this
log.debug(String.format(“User [%s] called method X with [%d]”, userName, i));
在這兩種情況下,您都將執(zhí)行所有必需的步驟來創(chuàng)建日志消息,而不知道您的日志記錄框架是否將使用該日志消息。最好在創(chuàng)建調(diào)試消息之前先檢查當(dāng)前日志級別。
// do this
if (log.isDebugEnabled()) {
log.debug(“User [” + userName + “] called method X with [” + i + “]”);
}
10.使用Apache Commons StringUtils.Replace代替String.replace
通常,String.replace方法可以正常工作并且非常有效,尤其是在使用Java 9的情況下。但是,如果您的應(yīng)用程序需要大量替換操作,而您尚未更新到最新的Java版本,則仍然有意義檢查更快,更有效的替代方案。
一種候選方法是?Apache Commons Lang的StringUtils.replace方法。正如Lukas Eder在?他最近的一篇博客文章中所描述的那樣,它的性能大大優(yōu)于Java 8的String.replace方法。?
它只需要最小的變化。您需要將Apache Commons Lang項目的Maven依賴項添加到應(yīng)用程序pom.xml中,并將String.replace方法的所有調(diào)用替換為StringUtils.replace方法。
// replace this
test.replace(“test”, “simple test”);
// with this
StringUtils.replace(test, “test”, “simple test”);
11.緩存昂貴的資源,例如數(shù)據(jù)庫連接
緩存是一種流行的解決方案,可以避免重復(fù)執(zhí)行昂貴或常用的代碼段。總體思路很簡單:重復(fù)使用這些資源要比一次又一次地創(chuàng)建新資源便宜。
一個典型的示例是在池中緩存數(shù)據(jù)庫連接。創(chuàng)建新連接需要花費時間,如果您重復(fù)使用現(xiàn)有連接,則可以避免。
您還可以在Java語言本身中找到其他示例。例如,Integer類的valueOf方法可緩存-128到127之間的值。您可能會說,創(chuàng)建一個新的Integer并不太昂貴,但是它的使用頻率很高,因此緩存最常用的值可以提供性能收益。
但是,當(dāng)您考慮緩存時,請記住,緩存的實現(xiàn)還會增加開銷。您需要花費更多的內(nèi)存來存儲可重用的資源,并且可能需要管理緩存以使資源可訪問或刪除過時的資源。
因此,在開始緩存任何資源之前,請確保您經(jīng)常使用它們以超過緩存實現(xiàn)的開銷。
摘要
如您所見,有時不需要太多工作即可提高應(yīng)用程序的性能。這篇文章中的大多數(shù)建議只需要少量的額外工作即可將它們應(yīng)用于您的代碼。
但是像往常一樣,最重要的建議是與語言無關(guān)的:
· 在知道必要之前不要進行優(yōu)化
· 使用探查器找到真正的瓶頸
· 首先解決最大的瓶頸
最后,開發(fā)這么多年我也總結(jié)了一套學(xué)習(xí)Java的資料與面試題,如果你在技術(shù)上面想提升自己的話,可以關(guān)注我,私信發(fā)送領(lǐng)取資料或者在評論區(qū)留下自己的聯(lián)系方式,有時間記得幫我點下轉(zhuǎn)發(fā)讓跟多的人看到哦。
總結(jié)
以上是生活随笔為你收集整理的java format 补足空格_11个简单的Java性能调优技巧的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kuka机器人if逻辑编程_KUKA机器
- 下一篇: 哈密温商大酒店具体位置