2015-10-19 113 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