2015年11月23日 星期一

[程式風格]Guard Clause

Guard Clause是一種程式的風格,通常會至少滿足其中一種以下的行為
1.檢查傳入的參數,如果檢驗不通過就回傳錯誤訊息
2.檢查物件的狀態,如果不符合function使用的物件就
3.簡單快速的處理明顯的邏輯

舉個例子像是以下的程式碼

  if(username!=null){

   if(password!=null){

    System.out.println("do something");
    //這邊是要處理的邏輯
   }else {

    System.out.println("password is null");

   }

  }else {

   System.out.println("username is null");

  }


我們可以知道username跟password皆不為null時才會執行程式
這邊我們可以閱讀是因為巢狀的條件還只有兩層,而且有進行縮排,要是越來越多層
或是程式碼一常,我們不見得可以閱讀程式的執行條件是什麼
以這個例子做出Guard Clause的話大概是長這個樣子

  if(username!=null && password!=null){

   System.out.println("do something");
   //這邊是要處理的邏輯
  }else if(password==null){

   System.out.println("password is null");

  }else{

   System.out.println("username is null");

  }


把要處理的邏輯直接表現出來,這樣是否感覺比較容易明白想要執行的邏輯呢?
我自己覺得還是看每個人習慣,不過這種程式風格就給各位當做參考了


參考資料:http://c2.com/cgi/wiki?GuardClause

2015年11月4日 星期三

[雜談]程式效能(一)

前幾天在FB上看到有大學生在某社團問作業:1加到10的程式怎麼做
然後看到一些很有趣的解答
剛好趁機談談程式的效能
由1加到n這個運算
很直觀的做法就是1+2+3+4+5+6.+..+n
用for迴圈表示就是i=1到n,result= result+i;
但是這樣你數字越大他要跑的迴圈就越常
同樣的計算結果你用高斯方法就是n*(n+1)/2
不管你的n有多大,程式永遠做一次加法,一次乘法,一次除法
這就是所謂好的演算法
那對效能有什麼影響呢,以下我們拿這個範例程式
第一個呼叫的是for迴圈的方法
第二個呼叫的是高斯方法
我使用了結果程式的時間減掉程式開始時間來計算每一個方法使用了多少毫秒
程式碼如下


import java.util.Date;



public class SumTest {



 public static void main(String[] args) {

  

  useForLoop(10000000);

  useGaussMethod(10000000);

 }



 public static void useForLoop(long input){

  long result = 0;

  long startTime = new Date().getTime();

  for(long i = 1;i<=input;i++){

   result = result + i;

  }

  System.out.println(result);

  long endTime = new Date().getTime();

  long totalTime = endTime-startTime;

  System.out.println(totalTime);

 }

 

 public static void useGaussMethod(long input){

  long startTime = new Date().getTime();

  long result = input*(input+1)/2;

  System.out.println(result);

  long endTime = new Date().getTime();

  long totalTime = endTime-startTime;

  System.out.println(totalTime);

 }

 

}



然後實驗開始啦,首先是n等於一萬
看起來兩個花的時間都是0毫秒沒什麼差別,於是我將n值放大到十萬
似乎有點差別了,不過可能是誤差,再放大n到100萬看看

差距來到了三毫秒,最後我們再放大n到1000萬
for回圈的消耗時間增加到了25毫秒
所以我們可以知道
在資料量小的時候,我們不一定能感覺出演算法的好壞
但是好的演算法在輸入的值越大的時候,節省的效能會越明顯
雖然一般來講先完成功能就好,但是當功能完成之後應該要去思考如何提升程式效能提高使用品質

之後會不會繼續這個主題就看我有沒有時間囉~_~+