2015-02-25 1 views
1

Мне нужно многократно добавлять строки (примерно 50 раз), что является подстрокой другого StringBuilder. Мне нужно сделать это для 30к входов. Мне требуется около 6 минут.Append Strings - проблема с производительностью - Java 6

StringBuilder input = new StringBuilder(10000); 
    StringBuilder output = new StringBuilder(10000); 

// цикл до конца файла, который считывает строки в переменную 'вход'

{ 
output.append(input.substring(1, 8)); 
output.append(input.substring(33, 45)); 
output.append(input.substring(20, 25)); // and so on 
} 

Это заняло около 6 минут.

Итак, я пытался что-то вроде

{ 


output.append(input.substring(1, 8) + output.append(input.substring(33, 45) + output.append(input.substring20, 25) + .. // and so on); 

}

Это, также принимая в то же время. Я знаю, что оба они одинаковы.

Но, хотя я использую StringBuilder, почему все же у меня есть отставание в производительности? Есть ли что-то, что я делаю неправильно?

Я упомянула: StringBuilder vs String concatenation in toString() in Java и String concatenation in Java - when to use +, StringBuilder and concat и еще несколько. Большинство из них предлагают использовать StringBuilder.

+0

Я предлагаю GC мониторинга деятельности в то время как ваш цикл продолжается. Вы можете столкнуться с ограничениями по памяти. –

+2

«Я знаю, что оба они одинаковы». Нет, они не. Второй код преобразует 'output' в строку на каждой итерации и использует конкатенацию строк. Вы определенно не хотите этого делать. –

+0

Возможно, это ваша проблема: «для цикла до конца файла, который считывает строки в переменную« input »? Покажите нам, как вы настраиваете читателя и как вы читаете. – Seelenvirtuose

ответ

1

Скорее всего проблема с производительностью в другом месте, так как это не должно занимать больше секунды. Я предлагаю вам профилировать ваше приложение, чтобы определить, где он фактически тратит время обработки.

long start = System.currentTimeMillis(); 
char[] chars = new char[500]; 
Arrays.fill(chars, '.'); 
for (int i = 0; i < 30000; i++) { 
    String input = new String(chars); 
    StringBuilder output = new StringBuilder(); 
    for (int j = 0; j < 50; j++) { 
     output.append(input, j * 10, j * 10 + 9); 
    } 
    String out = output.toString(); 
} 
System.out.println("Took: " + (System.currentTimeMillis() - start)/1e3 + " seconds"); 

печатает на 50 подстрок 30000 строк

Took: 0.058 seconds 
3

Вы можете определенно не создавать так много объектов, используя перегрузку append, которая позволяет указать подпоследовательность:

for (...) 
{ 
    output.append(input, 1, 8); 
    output.append(input, 33, 45); 
    output.append(input, 20, 25); 
} 

Это может или не может помочь вам. Конкатенацию строк во втором примере обязательно следует избегать - я удивлен, что это не делает разницу огромной ... что предполагает, что это может не быть добавлением, которое требует времени, но все, что читает ввод.

Чтобы проверить, что вы должны возможно попробовать петлю пустойfor, так что вы все еще читаете все тот же вход, но не добавляя к output вообще.

+0

Недолговечные строки просто увеличивают незначительную частоту GC.Шанс, что это проблема, исчезающе мал, особенно учитывая небольшой размер отдельных подстрок. –

+0

@MarkoTopolnik: Согласен. В принципе, мы действительно не можем сказать, куда идет время - отсюда мое предложение просто ездить на велосипеде через входные данные. –

 Смежные вопросы

  • Нет связанных вопросов^_^