"对于"循环,逐渐减慢

时间:2017-01-27 20:25:50

标签: java performance for-loop

我编写了一个显示循环进度的代码。部分代码:

String instantBinary = "";
for (int i = 0; i < Text.length(); i++) {
    //Sometimes the text is too long                        

    if (Text.length() > 100) {
        if (Text.length() % (Text.length() / 100) == i % (Text.length() / 100)) {
            WTProgress = "Translate Progress.. %" + (i * 100 / Text.length());
            System.out.println(WTProgress); 
        }
    }

    switch("" + Text.charAt(i)) {
        case "1": 
            instantBinary += "0000000";
            break;
        case "2": 
            instantBinary += "0000001";
            break;
        case "3": 
            instantBinary += "0000010";
            break;
        case "4": 
            instantBinary += "0000011";
            break;
        case "5": 
            instantBinary += "0000100";
            break;
        case "6": 
            instantBinary += "0000101";
            break;
        case "7": 
            instantBinary += "0000110";
            break;
        case "8": 
            instantBinary += "0000111";
            break;
        case "9": 
            instantBinary += "0001000";
            break;
        default:
            System.out.println("Unknown character found \"" + Text.charAt(i) + "\""):
    }

事实上,翻译代码并不短。有128个字符。但那不是问题。我最近尝试翻译300页的文字。它在5分钟内达到了25%。但是花了3个小时达到100%。我该如何解决这个问题?

编辑:我解决了这个问题。问题的根源是每次我对字符串执行+ =操作时,实际上我创建了一个新的字符串实例,并且它们越来越长。正如你所说,我使用StringBuilder解决了这个问题。翻译代码的工作速度至少快1000倍。感谢所有帮助过的人。

3 个答案:

答案 0 :(得分:8)

每次执行instantBinary+="00000000"时,您都在重新创建一个新的字符串对象,并将旧版String中的所有大量数据复制到其中(这就是Java的工作原理)
您应该创建一个StringBuilder对象并使用myStringBuilder.append ( "00000000" )并最终获取字符串,使用myStringBuilder.toString ()
更多信息here

答案 1 :(得分:6)

您正在内存中创建翻译。循环运行的时间越长,您需要的内存就越多。

  1. 使用-Xmx增加内存
  2. 使用StringBuilder。
  3. 使用正文所需的正确大小对其进行初始化(快速查看代码会告诉我它是原始文本大小的常量因素。

    StringBuilder instantBinary = new StringBuilder (text.length()*7);
    
  4. 打开字符,而不是字符串

    switch(Text.charAt(i)){
        case '1': instantBinary.append("0000000"); break;
    
  5. 不要在记忆中这样做。从一个文件中读取,即时将翻译写入输出文件。

答案 2 :(得分:3)

String(instantBinary)是一种不可变类型。每次对字符串执行+=操作时,实际上是在创建一个新的字符串实例,并且它们会越来越长。

尝试使用StringBufferStringBuilder代替instantBinary。