两个for循环非常慢 - Java解释器

时间:2017-08-25 08:47:38

标签: algorithm

我需要使用第一个循环遍历一个字符串数组,并在第二个循环中遍历每个子字符串(列):

字符串元素的外观如下:

"abc|def|ghi|jkl|mno|pqr|stu|vwx|yz"

I% = 6000 //Amount of elements in my string array

//For each row
FOR ROW% = 0 TO I%
    //Set the ROW
    STRING$ = ARRAY$(ROW%)

    // For each Column per row
    FOR COL% = 0 TO 9
        //Set the actual Column
        SUBSTR$(STRING$, CHR$(31), COL% + 1)
        //Do something with the column
        ROW$ = ROW$ + STRING$
    ENDLOOP
ENDLOOP

我希望你能理解语法,它几乎和BASIC一样。

有没有办法让这段代码更快?在阵列中有大约6000个条目,完成大约需要2分钟。

3 个答案:

答案 0 :(得分:1)

由于您没有给我们提供真实的代码,也没有提供有关语言/运行时环境的参考资料,因此很难为您提供帮助。

所以只是一些通用答案:

如果您的程序运行速度太慢,请从分析应用程序开始。例如。对于Java,JDK中包含免费的JVisualVM,或者有像JProfiler这样的专业工具。探查器告诉你代码的哪一部分正在消耗执行时间(就像@tobias_k一样,如果探查器指向你“ROW $ = ROW $ + STRING $”指令我也不会感到惊讶,但我们不妨完全错了。)

真的做这些测量。你不会相信开发人员认为他们知道程序性能不佳的原因,投入大量精力来改进程序的这一部分,只是为了看到零影响。因此,让分析器告诉您该程序的耗时部分是什么。

当您知道关键位置在哪里时,可以在本地进行改进(如果是row = row + string;,那么将rowString更改为StringBuilder将是这样的。或者重新考虑你的算法。如果您有例如O(2 ^ N)复杂度并且可以用O(N ^ 2)代替它,增益将是巨大的。

对不起,我不知道语言和执行环境就可以推荐......

答案 1 :(得分:0)

我认为问题不在于嵌入式循环。 6000元素现在并不是什么大不了的事。您使用的计算机/环境/语言/解释器非常慢,或者“使用列做某事”部分非常复杂或执行不佳。

答案 2 :(得分:0)

这是一种疯狂的猜测,但这一行看起来很可疑:ROW$ = ROW$ + STRING$

看起来您正在将当前子字符串添加到一些不断增长的字符串中。这个操作可能非常慢,并且在字符串获取的时间越长就越慢(正如您在注释中所描述的那样),因为这将在循环的每次迭代中创建一个新字符串,每次将前一个字符串的内容复制到一个新的内存位置,然后丢弃旧的值进行垃圾收集,有效地在内循环中提供二次复杂度。

根据您使用的语言,可能有更快的方法来构建字符串,例如StringBuilder与Java中的+,或收集要在列表中连接的字符串,然后在Python中使用''.join

如果该语言没有任何其他方法可以连接大量字符串,您可以尝试这样做:将所有字符串存储在列表中,然后成对加入该列表,直到所有字符串都加入为止。这应该将复杂度从O(n²/ 2)降低到O(n log n)。请参阅此示例:此处,+是您要加入的现有STRING$之一,而#是由ROW$ = ... + ...生成的新创建的字符串,以及块的长度对应于要连接的字符串的长度(以及要复制的内存块)。

What you do now: O(n^2/2)     Pairwise-joining: O(n log n)
+ + + + + + + +               + + + + + + + +
## + + + + + +                ## + + + + + +
### + + + + +                 ++ ## + + + +
#### + + + +                  ++ ++ ## + +
##### + + +                   ++ ++ ++ ##
###### + +                    #### ++ ++
####### +                     ++++ ####
########                      ########

2+3+...+8 = 35                4*2+2*4+1*8=8+8+8=24

最后,看一下你在评论中链接的website,似乎代码被翻译成实际的Java代码,所以你可以看看那些代码(在阅读中,或者在{ {3}},使用适当的分析工具)以更好地理解问题。您也可以尝试在生成的Java代码中修复它,例如使用StringBuilder,但重新生成代码时可能会丢失这些修复程序。总而言之,我建议首先使用Java,如果这是一个选项。