2015-10-19 211 views
-4

因爲我是編程新手,我在飛行中學習,我不知道在哪裏尋找答案:/我也非常抱歉,我無法解釋我的問題應該如何看起來像(使用foo和東西),我創建了我的目的,一個小程序,其中有幾個問題,看起來是這樣的:Java循環性能優化

我有一個輸入XLSX看起來像:

price: value1: 
10 2 
12 5 
9 1 
8 3 
11 3 
14 6 
17 4 

它有成千上萬的10S行,幾列和循環看起來像這樣(因爲代碼更長,我會用文字書寫,但概念是相同的):

Read and store whole xlxs into arrayList of arrayList (as there are different number of rows and columns). 

for (all criteria from list){ 

for (int i = 0; i <= xlsxNumOfRows; i++){ //go line by line from top of xlsx 

     if (value1 in i line (meets some criteria, for example >3)){ 
     boolen loopON = true; 
     for (int n = i; n <= xlsxNumOfRows && loopON = true; n++){ //go line by line from i line, until end or loopON 
      if (line n (meets some criteria, for example value i > value n)){ 
      loopON = false; //ends the n - loop, and continues with i loop 
      Cell cell = row.createCell(++columnCount); 
      cell.setCellValue(resultE);//write something into output xlsx, new column for every n-loop 

      } 
     } 
     } 
    } 
try (FileOutputStream outputStream = new FileOutputStream("D:/output.xlsx")) { 
      workbook.write(outputStream); 
} 

爲了解釋它的作用,是輸入xlsx文件包含價格隨時間變化的價格變化,其中附加值在時間點價格旁邊。我的計劃從第1分鐘開始,直到它看到需要的價值並進入並「購買」這個價格。之後,它看起來在哪裏「出售」 - 所以從入場價格看符合一些標準的下一個價格,並將結果標記爲xlsx。

我有幾千個不同的標準,所以整個循環運行幾千次,做同樣的事情,但在我和n循環嘗試不同的標準。在每個標準運行中爲output.xlsx創建一個新行(對於每個n循環新列,最後通常超過1000列)

1-變得非常慢,需要永遠(從eclipse運行,無需編譯成jar),任何想法如何使循環更有效?它遍歷整個表的次數儘可能多的標準我有(幾千) 2似乎它以某種方式存儲所有的值在最後寫xlsx,所以我遲早會得到堆空間錯誤(即使設置運行參數到8GB)。我如何設置xlsx寫入,它將寫入xlsx的東西,拋出它,然後從第二個標準開始第二個循環?我想我有workbook.write,新的FileOutputStream不在正確的位置,或者沒有正確的方式。程序逐漸變慢,直到它由於堆空間而下降爲止(取決於標準的數量 - 運行的i-循環的數量,性能越快或越低的PC) 3- loopON部分是否正確結束n循環? 四,最好是隻通過一次整個表,並在每一個在線檢查循環中的每個標準? 任何想法,一般如何編程循環具有更好的性能或任何東西非常讚賞

程序不編譯,因爲它需要大量的空間把整個事情放在這裏,我有更多的概念問題,它的工作原理,但並不像我想

+0

你大概的意思'loopON == TRUE'(或簡稱'loopON')代替'loopON = true'。 –

+0

請貼出有效的代碼,這個不會編譯。 –

+0

爲什麼你每次都在外層循環中覆蓋文件? – Kayaman

回答

2

你提的問題是非常難讀,但這裏有一些簡單的改進ü可以嘗試:

  1. 停止嘗試直接與.xlsx文件交互。將您的輸入轉換爲.csv文本文件,並讓您的批處理創建另一個.csv輸出
  2. 停止將所有內容存儲到內存中,使用流式處理,即按塊讀取輸入行(例如10乘10),並按塊編寫。
  3. 停止混合業務和演示文稿:對於每一行讀取,計算所有標準,不要根據XL顯示目標的標準閱讀每行一次。

當然您可以再次打開.csv作爲.xlsx。

如果因爲u需要在你的DATAS一些向前看2點是不適用的,U可能需要使用一些數據庫:Which embedded DB written in Java for a simple key/value store?

+0

謝謝你的寶貴意見,那就是我一直在尋找的。 – user3338991

1

首先它始終建議您張貼有效的代碼,這樣每個人都可以測試它並提供更有用的答案。

  1. 爲了完整這一點沒有被刪除,但根據下面的評論沒有積極的效果:關於你的問題堆:在Java中每個對象創建存儲在堆中。你在最內層循環中聲明你的單元格,並且在最內層循環中初始化它。你應該把你的單元格的聲明放在程序的開始部分。這將產生以下效果:如果將新對象分配給單元格,則舊單元將不再有引用,因此Java的垃圾回收器可以清理它。

    Cell cell; 
    
    for (all criteria from list){ 
        for (int i = 0; i <= xlsxNumOfRows; i++){ //go line by line from top of xlsx 
    
         if (value1 in i line (meets some criteria, for example >3)){ 
         boolen loopON = true; 
         for (int n = i; n <= xlsxNumOfRows && loopON = true; n++){ //go line by line from i line, until end or loopON 
    
          if (line n (meets some criteria, for example value i > value n)){ 
          loopON = false; //ends the n - loop, and continues with i loop 
          cell = row.createCell(++columnCount); 
          cell.setCellValue(resultE);//write something into output xlsx, new column for every n-loop 
          } 
         } 
         } 
        } 
        try (FileOutputStream outputStream = new FileOutputStream("D:/output.xlsx")) { 
         workbook.write(outputStream); 
        } 
    
  2. 在哪裏打開您的InputStream?看來你在最外層的循環中打開你的FileOutputStream?如果是這樣,你必須把它放在循環之外。您應該在程序開始時打開FileOutputStream,而不是在其中一個循環中。如果你在你的循環中打開它,你會得到越來越多的打開FileOutputStreams每個循環迭代,這些將永遠不會被關閉。對於Streams的工作,我建議你的情況:在程序的開始處打開InputStream和OutputStream,然後輸入你的循環。在循環之後,您必須關閉流,以避免任何問題和內存泄漏。

  3. 您的運行時問題:您有三個嵌套循環。在最壞的情況下,你將永遠有 「的標準號的」 O的運行時間(* 「xlsxNumOfRows」 * 「xlsxNumOfRows」。

+0

在循環之外聲明單元格對垃圾回收沒有積極的影響,原始格式與declaraion *裏面*循環是首選的(增加了範圍超出需要的地方是不好的)在這種特殊情況下,OP最有可能使用Apache POI(他發佈的POI API爲1:1),所以他創建的單元格在任何情況下都會保留在工作簿中。 – Durandal

+0

好的,謝謝你提供的信息。不知道POI API。 – siebenschlaefer

+0

感謝您提出寶貴的意見,這正是我一直在尋找的。我需要一段時間來嘗試和實施它們。再次抱歉沒有正確的格式化問題。 – user3338991