<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      有助于改善性能的Java代碼技巧

      前言

      程序的性能受到代碼質(zhì)量的直接影響。這次主要介紹一些代碼編寫(xiě)的小技巧和慣例。雖然看起來(lái)有些是微不足道的編程技巧,卻可能為系統(tǒng)性能帶來(lái)成倍的提升,因此還是值得關(guān)注的。

      慎用異常

      在Java開(kāi)發(fā)中,經(jīng)常使用try-catch進(jìn)行錯(cuò)誤捕獲,但是try-catch語(yǔ)句對(duì)系統(tǒng)性能而言是非常糟糕的。雖然一次try-catch中,無(wú)法察覺(jué)到她對(duì)性能帶來(lái)的損失,但是一旦try-catch語(yǔ)句被應(yīng)用于循環(huán)或是遍歷體內(nèi),就會(huì)給系統(tǒng)性能帶來(lái)極大的傷害。

      以下是一段將try-catch應(yīng)用于循環(huán)體內(nèi)的示例代碼:

          @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);
      
          }

      上面這段代碼運(yùn)行結(jié)果是:

      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);
          }

      運(yùn)行結(jié)果:

      useTime:6

      使用局部變量

      調(diào)用方法時(shí)傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時(shí)變量都保存在棧(Stack)中,速度快。其他變量,如靜態(tài)變量、實(shí)例變量等,都在堆(Heap)中創(chuàng)建,速度較慢。

      下面是一段使用局部變量進(jìn)行計(jì)算的代碼:

         @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);
      
          }

      運(yùn)行結(jié)果:

      useTime:5

      將局部變量替換為類(lèi)的靜態(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);
          }

      運(yùn)行結(jié)果:

      useTime:94

      通過(guò)上面兩次的運(yùn)行結(jié)果,可以看出來(lái)局部變量的訪(fǎng)問(wèn)速度遠(yuǎn)遠(yuǎn)高于類(lèi)成員變量。

      位運(yùn)算代替乘除法

      在所有的運(yùn)算中,位運(yùn)算是最為高效的。因此,可以嘗試使用位運(yùn)算代替部分算術(shù)運(yùn)算,來(lái)提高系統(tǒng)的運(yùn)行速度。最典型的就是對(duì)于整數(shù)的乘除運(yùn)算優(yōu)化。

      下面是一段使用算術(shù)運(yùn)算的代碼:

          @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);
          }

      運(yùn)行結(jié)果:

      useTime:1451

      將循環(huán)體中的乘除運(yùn)算改為等價(jià)的位運(yù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);
          }

      運(yùn)行結(jié)果:

      useTime:10

      上兩段代碼執(zhí)行了完全相同的功能,在每次循環(huán)中,都將整數(shù)乘以2,并除以2。但是運(yùn)行結(jié)果耗時(shí)相差非常大,所以位運(yùn)算的效率還是顯而易見(jiàn)的。

      提取表達(dá)式

      在軟件開(kāi)發(fā)過(guò)程中,程序員很容易有意無(wú)意地讓代碼做一些“重復(fù)勞動(dòng)”,在大部分情況下,由于計(jì)算機(jī)的高速運(yùn)行,這些“重復(fù)勞動(dòng)”并不會(huì)對(duì)性能構(gòu)成太大的威脅,但若希望將系統(tǒng)性能發(fā)揮到極致,提取這些“重復(fù)勞動(dòng)”相當(dāng)有意義。

      比如以下代碼中進(jìn)行了兩次算術(shù)計(jì)算:

          @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);
      
          }

      運(yùn)行結(jié)果:

      useTime:21

      仔細(xì)看能發(fā)現(xiàn),兩個(gè)計(jì)算表達(dá)式的后半部分完全相同,這也意味著在每次循環(huán)中,相同部分的表達(dá)式被重新計(jì)算了。

      那么改進(jì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);
          }

      運(yùn)行結(jié)果:

      useTime:11

      通過(guò)運(yùn)行結(jié)果我們可以看出來(lái)具體的優(yōu)化效果。

      同理,如果在某循環(huán)中需要執(zhí)行一個(gè)耗時(shí)操作,而在循環(huán)體內(nèi),其執(zhí)行結(jié)果總是唯一的,也應(yīng)該提取到循環(huán)體外。

      例如下面的代碼:

      for(int i=0;i<100000;i++){
          x[i] = Math.PI*Math.sin(y)*i;
      }

      應(yīng)該改進(jìn)成下面的代碼:

      //提取復(fù)雜,固定結(jié)果的業(yè)務(wù)邏輯處理到循環(huán)體外
      double p = Math.PI*Math.sin(y);
      for(int i=0;i<100000;i++){
          x[i] = p*i;
      }

      使用arrayCopy()

      數(shù)組復(fù)制是一項(xiàng)使用頻率很高的功能,JDK中提供了一個(gè)高效的API來(lái)實(shí)現(xiàn)它。

      /**
           * @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);

      如果在應(yīng)用程序中需要進(jìn)行數(shù)組復(fù)制,應(yīng)該使用這個(gè)函數(shù),而不是自己實(shí)現(xiàn)。

      下面來(lái)舉例:

          @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++){
                  //進(jìn)行復(fù)制
                  System.arraycopy(array,0,arraydest,0,size);
              }
              long useTime = System.currentTimeMillis()-start;
              System.out.println("useTime:"+useTime);
          }

      運(yùn)行結(jié)果:

      useTime:59

      相對(duì)應(yīng)地,如果在程序中,自己實(shí)現(xiàn)數(shù)組復(fù)制,其等價(jià)代碼如下:

          @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);
          }

      運(yùn)行結(jié)果:

      useTime:102

      通過(guò)運(yùn)行結(jié)果可以看出效果。

      因?yàn)镾ystem.arraycopy()函數(shù)是native函數(shù),通常native函數(shù)的性能要優(yōu)于普通函數(shù)。僅出于性能考慮,在程序開(kāi)發(fā)時(shí),應(yīng)盡可能調(diào)用native函數(shù)。

      使用Buffer進(jìn)行I/O操作

      除NIO外,使用Java進(jìn)行I/O操作有兩種基本方式;

      1、使用基于InpuStream和OutputStream的方式;

      2、使用Writer和Reader;

      無(wú)論使用哪種方式進(jìn)行文件I/O,如果能合理地使用緩沖,就能有效地提高I/O的性能。

      InputStream、OutputStream、Writer和Reader配套使用的緩沖組件。

      如下圖:

      使用緩沖組件對(duì)文件I/O進(jìn)行包裝,可以有效提升文件I/O的性能。

      下面是一個(gè)直接使用InputStream和OutputStream進(jìn)行文件讀寫(xiě)的代碼:

        @Test
          public void testOutAndInputStream(){
      
              try {
                  DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
                  long start = System.currentTimeMillis();
                  for(int i=0;i<10000;i++){
                      dataOutputStream.writeBytes(Objects.toString(i)+"\r\n");
                  }
                  dataOutputStream.close();
                  long useTime = System.currentTimeMillis()-start;
                  System.out.println("寫(xiě)入數(shù)據(jù)--useTime:"+useTime);
                  //開(kāi)始讀取數(shù)據(jù)
                  long startInput = System.currentTimeMillis();
                  DataInputStream dataInputStream = new DataInputStream(new FileInputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
      
                  while (dataInputStream.readLine() != null){
                  }
                  dataInputStream.close();
                  long useTimeInput = System.currentTimeMillis()-startInput;
                  System.out.println("讀取數(shù)據(jù)--useTimeInput:"+useTimeInput);
              }catch (Exception e){
                  e.printStackTrace();
              }
      
          }

      運(yùn)行結(jié)果:

      寫(xiě)入數(shù)據(jù)--useTime:660
      讀取數(shù)據(jù)--useTimeInput:274

      使用緩沖的代碼如下:

          @Test
          public void testBufferedStream(){
      
              try {
                  DataOutputStream dataOutputStream = new DataOutputStream(
                          new BufferedOutputStream(new FileOutputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt")));
                  long start = System.currentTimeMillis();
                  for(int i=0;i<10000;i++){
                      dataOutputStream.writeBytes(Objects.toString(i)+"\r\n");
                  }
                  dataOutputStream.close();
                  long useTime = System.currentTimeMillis()-start;
                  System.out.println("寫(xiě)入數(shù)據(jù)--useTime:"+useTime);
                  //開(kāi)始讀取數(shù)據(jù)
                  long startInput = System.currentTimeMillis();
                  DataInputStream dataInputStream = new DataInputStream(
                          new BufferedInputStream(new FileInputStream("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt")));
      
                  while (dataInputStream.readLine() != null){
                  }
                  dataInputStream.close();
                  long useTimeInput = System.currentTimeMillis()-startInput;
                  System.out.println("讀取數(shù)據(jù)--useTimeInput:"+useTimeInput);
              }catch (Exception e){
                  e.printStackTrace();
              }
      
          }

      運(yùn)行結(jié)果:

      寫(xiě)入數(shù)據(jù)--useTime:22
      讀取數(shù)據(jù)--useTimeInput:12

      通過(guò)運(yùn)行結(jié)果,我們能很明顯的看出來(lái)使用緩沖的代碼,無(wú)論在讀取還是寫(xiě)入文件上,性能都有了數(shù)量級(jí)的提升。

      使用Wirter和Reader也有類(lèi)似的效果。

      如下代碼:

         @Test
          public void testWriterAndReader(){
      
              try {
                  long start = System.currentTimeMillis();
                  FileWriter fileWriter = new FileWriter("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt");
                  for (int i=0;i<100000;i++){
                      fileWriter.write(Objects.toString(i)+"\r\n");
                  }
                  fileWriter.close();
                  long useTime = System.currentTimeMillis()-start;
                  System.out.println("寫(xiě)入數(shù)據(jù)--useTime:"+useTime);
                  //開(kāi)始讀取數(shù)據(jù)
                  long startReader = System.currentTimeMillis();
                  FileReader fileReader = new FileReader("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt");
                  while (fileReader.read() != -1){
                  }
                  fileReader.close();
                  long useTimeInput = System.currentTimeMillis()-startReader;
                  System.out.println("讀取數(shù)據(jù)--useTimeInput:"+useTimeInput);
              }catch (Exception e){
                  e.printStackTrace();
              }
      
          }

      運(yùn)行結(jié)果:

      寫(xiě)入數(shù)據(jù)--useTime:221
      讀取數(shù)據(jù)--useTimeInput:147

      對(duì)應(yīng)的使用緩沖的代碼:

          @Test
          public void testBufferedWriterAndReader(){
      
              try {
                  long start = System.currentTimeMillis();
                  BufferedWriter fileWriter = new BufferedWriter(
                          new FileWriter("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
                  for (int i=0;i<100000;i++){
                      fileWriter.write(Objects.toString(i)+"\r\n");
                  }
                  fileWriter.close();
                  long useTime = System.currentTimeMillis()-start;
                  System.out.println("寫(xiě)入數(shù)據(jù)--useTime:"+useTime);
                  //開(kāi)始讀取數(shù)據(jù)
                  long startReader = System.currentTimeMillis();
                  BufferedReader fileReader = new BufferedReader(
                          new FileReader("/IdeaProjects/client2/src/test/java/com/client2/cnblogtest/teststream.txt"));
                  while (fileReader.read() != -1){
                  }
                  fileReader.close();
                  long useTimeInput = System.currentTimeMillis()-startReader;
                  System.out.println("讀取數(shù)據(jù)--useTimeInput:"+useTimeInput);
              }catch (Exception e){
                  e.printStackTrace();
              }
      
          }

      運(yùn)行結(jié)果:

      寫(xiě)入數(shù)據(jù)--useTime:157
      讀取數(shù)據(jù)--useTimeInput:59

      通過(guò)運(yùn)行結(jié)果可以看出,使用了緩沖后,無(wú)論是FileReader還是FileWriter的性能都有較為明顯的提升。

      在上面的例子中,由于FileReader和FilerWriter的性能要優(yōu)于直接使用FileInputStream和FileOutputStream所以循環(huán)次數(shù)增加了10倍。

       

       

       

       

      后面會(huì)持續(xù)更新。。。

       

      posted @ 2019-05-31 01:10  紀(jì)莫  閱讀(1741)  評(píng)論(1)    收藏  舉報(bào)
      主站蜘蛛池模板: 在线观看无码av五月花| 中文字幕精品人妻丝袜| 国内精品人妻一区二区三区| 亚洲精品漫画一二三区| 井研县| 97人妻免费碰视频碰免| 精品不卡一区二区三区| 国产成人啪精品视频免费软件| 天堂亚洲免费视频| 国产羞羞的视频一区二区| 漂亮人妻被修理工侵犯| 偷拍专区一区二区三区| 亚洲熟女国产熟女二区三区| 国产精品久久久久鬼色| 国产精品一区二区久久精品| 激情视频乱一区二区三区| 人人玩人人添人人澡超碰| 精品国产成人网站一区在线| 欧洲一区二区中文字幕| 国产精品久久久久影院| 国产日韩综合av在线| 中文字幕日韩有码一区| 可以直接看的无码av| 亚洲成av人片天堂网无码| 国产欧美日韩视频怡春院| 一区二区三区国产偷拍| 国产精品香港三级国产av| 国产成人AV大片大片在线播放| 亚洲成人动漫av在线| 免费人成视频网站在线观看18| 欧美国产综合视频| 亚洲精品国产字幕久久麻豆| 最新偷拍一区二区三区| 18禁在线永久免费观看| 免费的特黄特色大片| 国产成人影院一区二区三区| 国产精品久久精品| 国产精品午夜爆乳美女视频| 激情人妻自拍中文夜夜嗨| 亚洲熟女综合色一区二区三区| 久久精品国产www456c0m|