Как найти всех наивными (“+” базирующийся) конкатенации строк в большой кодовой базе Java?

Преобразовать double[, ] в List<double>? Если вы ищете однострочник, то здесь

double[,] d = new double[,]
{
    {1.0, 2.0},
    {11.0, 22.0},
    {111.0, 222.0},
    {1111.0, 2222.0},
    {11111.0, 22222.0}
};
List<double> lst = d.Cast<double>().ToList()


Но если вы ищете что-то эффективное, я бы сказал, что вы не используете этот код.
Пожалуйста, следуйте одному из двух ответов, указанных ниже. Оба реализуют намного лучшие методы.
6
задан Uri 16 June 2009 в 20:41
поделиться

11 ответов

Просто убедитесь, что вы действительно понимаете, где на самом деле лучше использовать StringBuilder . Я не говорю, что вы не знаете, но определенно есть много людей, которые взяли бы такой код:

String foo = "Your age is: " + getAge();

и превратили бы его в:

StringBuilder builder = new StringBuilder("Your age is: ");
builder.append(getAge());
String foo = builder.toString();

, который является просто менее читаемой версией тоже самое. Часто наивным решением оказывается лучшее решение. Точно так же некоторые люди беспокоятся о следующем:

String x = "long line" + 
    "another long line";

когда на самом деле эта конкатенация выполняется во время компиляции.

Как совершенно правильно сказал Нсандер, сначала выясните, есть ли у вас проблема ...

12
ответ дан 8 December 2019 в 02:09
поделиться

Я почти уверен, что FindBugs может их обнаружить. Если нет, то это все еще очень полезно иметь под рукой.

Изменить: он действительно может найти конкатенаций в цикле , и это единственный раз, когда это действительно имеет значение.

13
ответ дан 8 December 2019 в 02:09
поделиться

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

Взгляните на этот код:

public class StringBuilding {
  public static void main(String args[]) {
    String a = "The first part";
    String b = "The second part";
    String res = a+b;

    System.gc(); // Inserted to make it easier to see "before" and "after" below

    res = new StringBuilder().append(a).append(b).toString();
  }
}

Если вы скомпилируете его и дизассемблируете с помощью javap, вы получите следующее.

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #2; //String The first part
   2:   astore_1
   3:   ldc     #3; //String The second part
   5:   astore_2
   6:   new     #4; //class java/lang/StringBuilder
   9:   dup
   10:  invokespecial   #5; //Method java/lang/StringBuilder."<init>":()V
   13:  aload_1
   14:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   17:  aload_2
   18:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   21:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   24:  astore_3
   25:  invokestatic    #8; //Method java/lang/System.gc:()V
   28:  new     #4; //class java/lang/StringBuilder
   31:  dup
   32:  invokespecial   #5; //Method java/lang/StringBuilder."<init>":()V
   35:  aload_1
   36:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   39:  aload_2
   40:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   43:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   46:  astore_3
   47:  return

Как видите, 6-21 в значительной степени идентичны 28-43. Не так много оптимизации, верно?

Изменить: Проблема с циклом все же допустима ...

2
ответ дан 8 December 2019 в 02:09
поделиться

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

2
ответ дан 8 December 2019 в 02:09
поделиться

Почему бы не использовать профилировщик, чтобы найти действительно важные "наивные" конкатенации строк? Переключайтесь на более подробный StringBuffer, только если он вам действительно нужен.

10
ответ дан 8 December 2019 в 02:09
поделиться

Вместо того, чтобы искать просто + , ищите "+ и + " те, вероятно, найдут подавляющее большинство. случаи, когда вы объединяете несколько переменных, будут сложнее.

1
ответ дан 8 December 2019 в 02:09
поделиться

If you have a huge code base you probably have lots of hotspots, which may or may not involve "+" concatenation. Just run your usual profiler, and fix the big ones, regardless of what kind of construct they are.

It would be an odd approach to fix just one class of (potential) bottleneck, rather than fixing the actual bottlenecks.

1
ответ дан 8 December 2019 в 02:09
поделиться

С PMD вы можете писать правила с помощью XPath или используя синтаксис Java. Возможно, стоит изучить, соответствует ли он оператору конкатенации строк - это определенно входит в сферу статического анализа. Это настолько расплывчатая идея, что я собираюсь сделать эту «вики сообщества»; если кто-то еще хочет уточнить (или придумать свой собственный ответ по этим строкам), пожалуйста!

0
ответ дан 8 December 2019 в 02:09
поделиться

Forget it - your JVM most likely does it already - see the JLS, 15.18.1.2 Optimization of String Concatenation:

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

0
ответ дан 8 December 2019 в 02:09
поделиться

Скорее всего, вы снизите производительность и ухудшите читабельность кода . Компилятор уже выполняет эту оптимизацию, и, если вы не зациклились, обычно он справляется лучше. Более того, в JDK 8 они могут выйти с StringUberBuilder, и весь ваш код, использующий StringBuilder, будет работать медленнее, а конкатенированные строки «+» выиграют от нового класса.

«Мы должны забыть о небольшой эффективности, например 97% случаев: преждевременная оптимизация - корень всех зол. Тем не менее, мы не должны упускать наши возможности в этих критических 3% ». - Дональд Кнут

3
ответ дан 8 December 2019 в 02:09
поделиться

IntelliJ может найти их с помощью «структурного поиска». Вы выполняете поиск по запросу «$ a + $ b» и устанавливаете характеристики как $ a, так и $ b как тип java.lang.String.

Однако, если у вас есть IntelliJ, он, вероятно, имеет встроенную инспекцию, которая в любом случае лучше найдет то, что вам нужно.

2
ответ дан 8 December 2019 в 02:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: