前言
站在用戶的角度思考問題,與客戶深入溝通,找到霍林郭勒網站設計與霍林郭勒網站推廣的解決方案,憑借多年的經驗,讓設計與互聯網技術結合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網站建設、成都做網站、企業(yè)官網、英文網站、手機端網站、網站推廣、域名注冊、網頁空間、企業(yè)郵箱。業(yè)務覆蓋霍林郭勒地區(qū)。
程序的性能受到代碼質量的直接影響。這次主要介紹一些代碼編寫的小技巧和慣例。雖然看起來有些是微不足道的編程技巧,卻可能為系統性能帶來成倍的提升,因此還是值得關注的。
慎用異常
在Java開發(fā)中,經常使用try-catch進行錯誤捕獲,但是try-catch語句對系統性能而言是非常糟糕的。雖然一次try-catch中,無法察覺到她對性能帶來的損失,但是一旦try-catch語句被應用于循環(huán)或是遍歷體內,就會給系統性能帶來極大的傷害。
以下是一段將try-catch應用于循環(huán)體內的示例代碼:
@Test public void test11() { long start = System.currentTimeMillis(); int a = 0; for(int i=0;i<1000000000;i++){ try { a++; }catch (Exception e){ e.printStackTrace(); } } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
上面這段代碼運行結果是:
useTime:10
下面是一段將try-catch移到循環(huán)體外的代碼,那么性能就提升了將近一半。如下:
@Test public void test(){ long start = System.currentTimeMillis(); int a = 0; try { for (int i=0;i<1000000000;i++){ a++; } }catch (Exception e){ e.printStackTrace(); } long useTime = System.currentTimeMillis()-start; System.out.println(useTime); }
運行結果:
useTime:6
使用局部變量
調用方法時傳遞的參數以及在調用中創(chuàng)建的臨時變量都保存在棧(Stack)中,速度快。其他變量,如靜態(tài)變量、實例變量等,都在堆(Heap)中創(chuàng)建,速度較慢。
下面是一段使用局部變量進行計算的代碼:
@Test public void test11() { long start = System.currentTimeMillis(); int a = 0; for(int i=0;i<1000000000;i++){ a++; } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:5
將局部變量替換為類的靜態(tài)變量:
static int aa = 0; @Test public void test(){ long start = System.currentTimeMillis(); for (int i=0;i<1000000000;i++){ aa++; } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:94
通過上面兩次的運行結果,可以看出來局部變量的訪問速度遠遠高于類成員變量。
位運算代替乘除法
在所有的運算中,位運算是最為高效的。因此,可以嘗試使用位運算代替部分算術運算,來提高系統的運行速度。最典型的就是對于整數的乘除運算優(yōu)化。
下面是一段使用算術運算的代碼:
@Test public void test11() { long start = System.currentTimeMillis(); int a = 0; for(int i=0;i<1000000000;i++){ a*=2; a/=2; } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:1451
將循環(huán)體中的乘除運算改為等價的位運算,代碼如下:
@Test public void test(){ long start = System.currentTimeMillis(); int aa = 0; for (int i=0;i<1000000000;i++){ aa<<=1; aa>>=1; } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:10
上兩段代碼執(zhí)行了完全相同的功能,在每次循環(huán)中,都將整數乘以2,并除以2。但是運行結果耗時相差非常大,所以位運算的效率還是顯而易見的。
提取表達式
在軟件開發(fā)過程中,程序員很容易有意無意地讓代碼做一些“重復勞動”,在大部分情況下,由于計算機的高速運行,這些“重復勞動”并不會對性能構成太大的威脅,但若希望將系統性能發(fā)揮到極致,提取這些“重復勞動”相當有意義。
比如以下代碼中進行了兩次算術計算:
@Test public void testExpression(){ long start = System.currentTimeMillis(); double d = Math.random(); double a = Math.random(); double b = Math.random(); double e = Math.random(); double x,y; for(int i=0;i<10000000;i++){ x = d*a*b/3*4*a; y = e*a*b/3*4*a; } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:21
仔細看能發(fā)現,兩個計算表達式的后半部分完全相同,這也意味著在每次循環(huán)中,相同部分的表達式被重新計算了。
那么改進一下后就變成了下面的樣子:
@Test public void testExpression99(){ long start = System.currentTimeMillis(); double d = Math.random(); double a = Math.random(); double b = Math.random(); double e = Math.random(); double p,x,y; for(int i=0;i<10000000;i++){ p = a*b/3*4*a; x = d*p; y = e*p; } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:11
通過運行結果我們可以看出來具體的優(yōu)化效果。
同理,如果在某循環(huán)中需要執(zhí)行一個耗時操作,而在循環(huán)體內,其執(zhí)行結果總是唯一的,也應該提取到循環(huán)體外。
例如下面的代碼:
for(int i=0;i<100000;i++){ x[i] = Math.PI*Math.sin(y)*i; }
應該改進成下面的代碼:
//提取復雜,固定結果的業(yè)務邏輯處理到循環(huán)體外 double p = Math.PI*Math.sin(y); for(int i=0;i<100000;i++){ x[i] = p*i; }
使用arrayCopy()
數組復制是一項使用頻率很高的功能,JDK中提供了一個高效的API來實現它。
/** * @param src the source array. * @param srcPos starting position in the source array. * @param dest the destination array. * @param destPos starting position in the destination data. * @param length the number of array elements to be copied. * @exception IndexOutOfBoundsException if copying would cause * access of data outside array bounds. * @exception ArrayStoreException if an element in the <code>src</code> * array could not be stored into the <code>dest</code> array * because of a type mismatch. * @exception NullPointerException if either <code>src</code> or * <code>dest</code> is <code>null</code>. */ public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
如果在應用程序中需要進行數組復制,應該使用這個函數,而不是自己實現。
下面來舉例:
@Test public void testArrayCopy(){ int size = 100000; int[] array = new int[size]; int[] arraydest = new int[size]; for(int i=0;i<array.length;i++){ array[i] = i; } long start = System.currentTimeMillis(); for (int k=0;k<1000;k++){ //進行復制 System.arraycopy(array,0,arraydest,0,size); } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:59
相對應地,如果在程序中,自己實現數組復制,其等價代碼如下:
@Test public void testArrayCopy99(){ int size = 100000; int[] array = new int[size]; int[] arraydest = new int[size]; for(int i=0;i<array.length;i++){ array[i] = i; } long start = System.currentTimeMillis(); for (int k=0;k<1000;k++){ for(int i=0;i<size;i++){ arraydest[i] = array[i]; } } long useTime = System.currentTimeMillis()-start; System.out.println("useTime:"+useTime); }
運行結果:
useTime:102
通過運行結果可以看出效果。
因為System.arraycopy()函數是native函數,通常native函數的性能要優(yōu)于普通函數。僅出于性能考慮,在程序開發(fā)時,應盡可能調用native函數。
標題名稱:通過Java代碼技巧改善性能
鏈接地址:http://muchs.cn/article32/ihcdpc.html
成都網站建設公司_創(chuàng)新互聯,為您提供面包屑導航、App開發(fā)、標簽優(yōu)化、網站導航、靜態(tài)網站、商城網站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯