欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

分享Java性能調(diào)優(yōu)的11個實用技巧

 更新時間:2017年11月30日 15:19:31   投稿:mdxy-dxy  
這些建議中的大多數(shù)都是基于Java的,但是也不一定,也有一些是可以應(yīng)用于所有的應(yīng)用程序和編程語言的。在我們分享基于Java的性能調(diào)優(yōu)技巧之前,讓我們先討論一下這些通用的性能調(diào)優(yōu)技巧

大多數(shù)開發(fā)人員認(rèn)為性能優(yōu)化是個比較復(fù)雜的問題,需要大量的經(jīng)驗和知識。是的,這并不沒有錯。誠然,優(yōu)化應(yīng)用程序以獲得最好的性能并不是一件容易的事情,但這并不意味著你在沒有獲得這些經(jīng)驗和知識之前就不能做任何事。下面有幾個很容易遵循的建議和最佳實踐能夠幫你創(chuàng)建一個性能良好的應(yīng)用程序。

這些建議中的大多數(shù)都是基于Java的,但是也不一定,也有一些是可以應(yīng)用于所有的應(yīng)用程序和編程語言的。在我們分享基于Java的性能調(diào)優(yōu)技巧之前,讓我們先討論一下這些通用的性能調(diào)優(yōu)技巧。

1.在必要之前,先不要優(yōu)化

這可能是最最重要的性能調(diào)優(yōu)技巧之一。你應(yīng)該遵循常見的最佳實踐,并嘗試有效地實現(xiàn)你的用例。但這并不意味著在證明它是必要之前,替換任何標(biāo)準(zhǔn)庫或構(gòu)建復(fù)雜的優(yōu)化。

在大多數(shù)情況下,過早的優(yōu)化占用了大量的時間,使得代碼難以讀取和維護(hù)。更糟糕的是,這些優(yōu)化通常不會帶來任何好處,因為你花費了大量時間來優(yōu)化應(yīng)用程序的非關(guān)鍵部分。

那么,你如何證明你需要優(yōu)化某些東西呢?

首先,你需要確定應(yīng)用程序代碼的速度,例如,為所有API調(diào)用指定一個最大響應(yīng)時間,或者指定在特定時間范圍內(nèi)導(dǎo)入的記錄數(shù)量。完成之后,你可以度量應(yīng)用程序的哪些部分太慢而需要改進(jìn)。當(dāng)這樣做之后,那么請繼續(xù)看第二個調(diào)優(yōu)技巧。

2.使用分析器來找到真正的瓶頸

在你遵循第一條建議,并確定你的應(yīng)用程序的某些部分的確需要改進(jìn)之后,問自己從哪里開始?

你可以用兩種方法來解決這個問題:

  1. 你可以看一下你的代碼,從看起來可疑或者你覺得它可能會產(chǎn)生問題的部分開始。
  2. 或者使用分析器,獲取代碼中每個部分的行為和性能的詳細(xì)信息。

至于為什么應(yīng)該總是遵循第二種方法。

答案應(yīng)該很明顯,基于分析器的方法能讓你更好地理解代碼的性能含義,并允許你關(guān)注最關(guān)鍵的部分。如果你曾經(jīng)使用過分析器,你將會驚訝于代碼的哪些部分造成了性能問題。然而,很多時候,你的第一次猜想會把你引向錯誤的方向。

3 .為整個應(yīng)用程序創(chuàng)建性能測試套件

這是另一個幫助你避免許多意想不到問題的一般技巧,這些問題通常發(fā)生在性能改進(jìn)部署到生產(chǎn)環(huán)境之后。你應(yīng)該經(jīng)常定義測試整個應(yīng)用程序的性能測試套件,并在你完成性能改進(jìn)之前和之后運行它。

這些額外的測試運行將幫助你識別更改的功能和性能方面的影響,并確保你不會發(fā)布一個弊大于利的更新。如果你的任務(wù)運行于應(yīng)用程序的多個不同部分比如數(shù)據(jù)庫或緩存,這一點尤其重要。

4.首先解決最大的瓶頸問題

在創(chuàng)建了測試套件并使用分析器對應(yīng)用程序進(jìn)行分析之后,你就有了一個需要提高性能的問題列表,這很好,但它仍然不能回答你應(yīng)該從哪里開始的問題。你可以從那些可以快速搞定的開始,亦或者從最重要的問題開始。

當(dāng)然前者很誘人,因為這很快就能出結(jié)果。有時,可能需要說服其他團隊成員或你的管理層,性能分析是值得的。

但總的來說,我建議首先著手處理最重要的性能問題。這將為你提供最大的性能改進(jìn),而且你可能只需要修復(fù)這些問題中的幾個就可以解決你的性能需求。

在了解通用性能調(diào)優(yōu)技巧之后,讓我們再來仔細(xì)看看一些特定于Java的調(diào)優(yōu)技巧。

5.使用StringBuilder以編程方式連接字符串

在Java中有許多不同的連接字符串的選項。例如,可以使用一個簡單的+或+ =、老的StringBuffer或StringBuilder。 

那么,你應(yīng)該選擇哪種方法呢? 

答案取決于連接字符串的代碼。如果你以編程方式向字符串中添加新內(nèi)容,例如,在for循環(huán)中,你應(yīng)該使用StringBuilder。它比StringBuffer更容易使用和提供更好的性能。但是請記住,StringBuilder與StringBuffer不同,它不是線程安全的,而且可能不適合所有用例。 

你只需要實例化一個新的StringBuilder,并調(diào)用append方法在字符串中添加一個新的部分。當(dāng)你添加了所有的部分后,可以調(diào)用toString()方法來檢索連接字符串。 

下面的代碼片段展示了一個簡單的示例。在每次迭代過程中,這個循環(huán)將i轉(zhuǎn)換成一個字符串,并將其添加到StringBuilder sb的空間中,因此到最后,這段代碼寫入“this is test0123456789”到日志文件。 

StringBuilder sb = new StringBuilder(“This is a test”);
for (int i=0; i<10; i++) {
 sb.append(i);
 sb.append(” “);
}
log.info(sb.toString());

正如在代碼片段中看到的,你可以為構(gòu)造函數(shù)方法提供字符串的第一個元素。這將創(chuàng)建一個新的StringBuilder,其中包含提供的字符串和16個額外字符的容量。當(dāng)你向StringBuilder中添加更多字符時,JVM將動態(tài)地改變StringBuilder的大小。

如果你已經(jīng)知道自己的字符串包含多少字符,那么你可以向不同的構(gòu)造函數(shù)方法提供這個數(shù)字,以實例化一個具有被定義容量的StringBuilder。這進(jìn)一步提高了它的效率,因為它不需要動態(tài)擴展它的容量。

6.在聲明中使用+連接字符串

當(dāng)你在Java中實現(xiàn)第一個應(yīng)用程序時,可能有人告訴你不應(yīng)該用+來連接字符串。如果在應(yīng)用程序邏輯中連接字符串這是正確的。字符串是不可變的,每個字符串連接的結(jié)果存儲在一個新的字符串對象中。這需要額外的內(nèi)存,并降低應(yīng)用程序的速度,特別是在循環(huán)中連接多個字符串時。

在這些情況下,你應(yīng)該遵循tip 5并使用StringBuilder。

但如果你只是將一個字符串分解成多行來提高代碼的可讀性,那就不是這樣了。

Query q = em.createQuery(“SELECT a.id, a.firstName, a.lastName ”
+ “FROM Author a ”
+ “WHERE a.id = :id”);

在這些情況下,你應(yīng)該用一個簡單的+來連接你的字符串。Java編譯器將優(yōu)化它并在編譯時執(zhí)行連接。因此,在運行時,代碼只使用1個字符,不需要連接。

7.盡可能使用基本數(shù)據(jù)類型

另一種避免開銷,提高應(yīng)用程序性能的快速方法就是使用原始數(shù)據(jù)類型而不是它們的包裝類。因此,最好是使用int而不是Integer,或者是double而不是Double。這將讓JVM將值存儲在堆棧中,以減少內(nèi)存消耗,并更有效地處理它。

8.盡量避免BigInteger和BigDecimal

由于我們已經(jīng)討論了數(shù)據(jù)類型,我們再來看下BigIntegerBigDecimal。尤其是后者,由于其精度高而受歡迎。但這是有代價的。 
BigInteger和BigDecimal比簡單的long或double需要更多的內(nèi)存,并且大大降低所有的計算速度。因此,如果你需要額外的精度,或者你的數(shù)字超過了一個long范圍,最好三思而后行。這可能是你在提升性能問題中唯一需要更改的地方,特別是當(dāng)你正在實現(xiàn)一個數(shù)學(xué)算法。 

9.首先檢查當(dāng)前日志級別

這個建議是顯而易見的,但不幸的是,你會發(fā)現(xiàn)許多代碼忽略它。在創(chuàng)建調(diào)試消息之前,應(yīng)該先檢查當(dā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)前日志級別。

10.使用Apache Commons StringUtils.Replace 代替String.replace

一般來說,String.replace 方法工作得很好,而且非常高效,特別是如果你使用的是Java 9。但是,如果應(yīng)用程序需要大量的替換操作,并且你還沒有更新到最新的Java版本,那么檢查更快和更有效的替代方案仍然是有意義的。

一個候選就是 Apache Commons Lang's StringUtils.replace 方法。正如Lukas Eder在他最近的一篇博客文章中所描述的那樣,它大大超過了Java 8的String.replace 方法。 

它只需要很小的改變。你只需要為Apache's Commons Lang 項目增加一個Maven依賴項到你的應(yīng)用pom.xml,并用StringUtils.replace方法替換所有String.replace方法的調(diào)用。 

// 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)建新連接需要時間,如果重用現(xiàn)有連接,則可以避免。

還可以在Java語言本身中找到其他示例。例如,Integer類的valueOf方法緩存了- 128和127之間的值。你可能會說,創(chuàng)建一個新整數(shù)并不太貴,但它經(jīng)常使用,緩存最常用的值提供了性能方面的好處。

但當(dāng)你考慮緩存時,請記住,緩存實現(xiàn)也會產(chǎn)生開銷。你需要花費額外的內(nèi)存來存儲可重用資源,因此可能需要管理你的緩存,以使資源能夠訪問或刪除過時的資源。

因此,在你開始緩存任何資源之前,請確保是經(jīng)常使用。

總結(jié)

正如你所看到的,提高應(yīng)用程序的性能有時不需要做大量的工作。這篇文章中的大多數(shù)建議,其實只需要稍微的努力就可以將它們應(yīng)用到代碼中。

但通常最重要的建議是很編程語言無關(guān)的:

  1. 在你知道有必要之前,不要優(yōu)化
  2. 使用分析器來找到真正的瓶頸
  3. 首先解決最大的瓶頸問題

原文鏈接:11 Simple Java Performance Tuning Tips(責(zé)編/魏偉)

相關(guān)文章

  • Spring Boot 啟動、停止、重啟、狀態(tài)腳本

    Spring Boot 啟動、停止、重啟、狀態(tài)腳本

    今天給大家分享Spring Boot 項目腳本(啟動、停止、重啟、狀態(tài)),通過示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-06-06
  • IDEA如何實現(xiàn)批量修改變量名

    IDEA如何實現(xiàn)批量修改變量名

    這篇文章主要介紹了IDEA如何實現(xiàn)批量修改變量名問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Kotlin Coroutines執(zhí)行異步加載示例詳解

    Kotlin Coroutines執(zhí)行異步加載示例詳解

    這篇文章主要給大家介紹了關(guān)于Kotlin Coroutines執(zhí)行異步加載的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • SpringCloud高可用配置中心Config詳解

    SpringCloud高可用配置中心Config詳解

    Spring Cloud Config 是一個解決分布式系統(tǒng)的配置管理方案,它包含了 server 和 client 兩個部分,這篇文章主要介紹了SpringCloud之配置中心Config(高可用),需要的朋友可以參考下
    2022-04-04
  • SpringBoot使用Redisson實現(xiàn)分布式鎖(秒殺系統(tǒng))

    SpringBoot使用Redisson實現(xiàn)分布式鎖(秒殺系統(tǒng))

    這篇文章主要為大家詳細(xì)介紹了SpringBoot使用Redisson實現(xiàn)分布式鎖,秒殺系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Java中的Semaphore信號量簡單使用代碼實例

    Java中的Semaphore信號量簡單使用代碼實例

    這篇文章主要介紹了Java中的Semaphore信號量簡單使用代碼實例,Semaphore是用來保護(hù)一個或者多個共享資源的訪問,Semaphore內(nèi)部維護(hù)了一個計數(shù)器,其值為可以訪問的共享資源的個數(shù),一個線程要訪問共享資源,需要的朋友可以參考下
    2023-12-12
  • springboot亂碼問題排查思路解析

    springboot亂碼問題排查思路解析

    這篇文章主要為大家介紹了springboot亂碼問題排查思路解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 16 個有用的的Java工具類(小結(jié))

    16 個有用的的Java工具類(小結(jié))

    這篇文章主要介紹了16 個有用的的Java工具類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • JAVA正則表達(dá)式提取key-value類型字符值代碼實例

    JAVA正則表達(dá)式提取key-value類型字符值代碼實例

    這篇文章主要給大家介紹了關(guān)于JAVA正則表達(dá)式提取key-value類型字符值的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-10-10
  • Java終止線程實例和stop()方法源碼閱讀

    Java終止線程實例和stop()方法源碼閱讀

    這篇文章主要介紹了Java終止線程實例和stop()方法源碼閱讀,具有一定借鑒價值,需要的朋友可以參考下
    2017-12-12

最新評論