Лучше ли использовать String.format поверх конкатенации строк в Java? - PullRequest
238 голосов
/ 29 мая 2009

Есть ли ощутимая разница между использованием String.format и конкатенацией строк в Java?

Я склонен использовать String.format, но иногда проскальзываю и использую конкатенацию. Мне было интересно, был ли один лучше другого.

На мой взгляд, String.format дает вам больше возможностей для "форматирования" строки; и конкатенация означает, что вам не нужно беспокоиться о случайном добавлении% s или об отсутствии.

String.format также короче.

Какой из них более читабелен, зависит от того, как работает ваша голова.

Ответы [ 14 ]

2 голосов
/ 29 мая 2009

Я не делал каких-либо конкретных тестов, но я думаю, что объединение может быть быстрее. String.format () создает новый Formatter, который, в свою очередь, создает новый StringBuilder (размером всего 16 символов). Это значительная часть накладных расходов, особенно если вы форматируете более длинную строку, а StringBuilder продолжает изменять размер.

Однако конкатенация менее полезна и труднее для чтения. Как всегда, стоит сделать тест на вашем коде, чтобы увидеть, что лучше. Различия могут быть незначительными в серверном приложении после загрузки пакетов ресурсов, локалей и т. Д. В память и кода JITted.

Может быть, в качестве лучшей практики, было бы неплохо создать свой собственный Formatter с соответствующим размером StringBuilder (Appendable) и Locale и использовать его, если вам нужно много форматирования.

0 голосов
/ 30 мая 2019

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

Я использовал ту же программу, которая использовалась Icaro в его ответе выше, и я добавил в него дополнительный код для использования MessageFormat для объяснения чисел исполнения.

  public static void main(String[] args) {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      String s = "Hi " + i + "; Hi to you " + i * 2;
    }
    long end = System.currentTimeMillis();
    System.out.println("Concatenation = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      String s = String.format("Hi %s; Hi to you %s", i, +i * 2);
    }
    end = System.currentTimeMillis();
    System.out.println("Format = " + ((end - start)) + " millisecond");

    start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      String s = MessageFormat.format("Hi %s; Hi to you %s", i, +i * 2);
    }
    end = System.currentTimeMillis();
    System.out.println("MessageFormat = " + ((end - start)) + " millisecond");
  }

Конкатенация = 69 миллисекунд

Формат = 1435 миллисекунд

MessageFormat = 200 миллисекунд

ОБНОВЛЕНИЯ:

Согласно отчету SonarLint, строки формата в стиле Printf должны использоваться правильно (squid: S3457)

Поскольку строки формата в стиле printf интерпретируются во время выполнения, а не проверяются компилятором, они могут содержать ошибки, которые приводят к созданию неправильных строк. Это правило статически проверяет соответствие строк формата в стиле printf их аргументам при вызове методов format (...) java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat и java.io. Классы .PrintWriter и методы printf (...) классов java.io.PrintStream или java.io.PrintWriter.

Я заменил стиль printf на фигурные скобки, и я получил кое-что интересное, как показано ниже.

Конкатенация = 69 миллисекунд
Формат = 1107 миллисекунд
Формат: фигурные скобки = 416 миллисекунд
MessageFormat = 215 миллисекунда
Формат сообщения: фигурные скобки = 2517 миллисекунда

Мой вывод:
Как я подчеркивал выше, использование String.format с фигурными скобками должно быть хорошим выбором для получения преимуществ хорошей читаемости, а также производительности.

0 голосов
/ 10 мая 2019

Требуется немного времени, чтобы привыкнуть к String.Format, но в большинстве случаев оно того стоит. В мире NRA (никогда ничего не повторяйте) чрезвычайно полезно хранить ваши токенизированные сообщения (ведение журнала или пользователя) в библиотеке констант (я предпочитаю то, что равно статическому классу) и вызывать их при необходимости с помощью String.Format независимо от того, используете ли вы локализуются или нет. Попытки использовать такую ​​библиотеку с методом конкатенации труднее читать, устранять неполадки, корректировать и управлять любым подходом, требующим конкатенации. Замена - это вариант, но я сомневаюсь, что он эффективен. После многих лет использования моя самая большая проблема с String.Format заключается в том, что длительность вызова неудобно велика, когда я передаю его в другую функцию (например, Msg), но это легко обойти с помощью пользовательской функции, служащей псевдонимом. .

0 голосов
/ 28 сентября 2011

Невозможно сравнить String Concatenation и String.Format с помощью указанной выше программы.

Вы можете попробовать это также поменять местами использование вашего String.Format и Concatenation в вашем блоке кода, как показано ниже

public static void main(String[] args) throws Exception {      
  long start = System.currentTimeMillis();

  for( int i=0;i<1000000; i++){
    String s = String.format( "Hi %s; Hi to you %s",i, + i*2);
  }

  long end = System.currentTimeMillis();
  System.out.println("Format = " + ((end - start)) + " millisecond");
  start = System.currentTimeMillis();

  for( int i=0;i<1000000; i++){
    String s = "Hi " + i + "; Hi to you " + i*2;
  }

  end = System.currentTimeMillis();
  System.out.println("Concatenation = " + ((end - start)) + " millisecond") ;
}

Вы будете удивлены, увидев, что Формат работает здесь быстрее. Это связано с тем, что созданные объекты могут быть не выпущены, и может возникнуть проблема с выделением памяти и, следовательно, с производительностью.

...