Skip to content

Conversation

@pepness
Copy link
Member

@pepness pepness commented Oct 12, 2021

I did some cleaning to the enterprise module with the Inspect & Transform tool. I divided the cleaning in 8 parts/commits. This is the 4th PR.

Cleaning enterprise module part 4:

  • Replace length one String in String.indexOf ("c" -> 'c')
  • Remove redundant String.toString()
  • Replace useless use of StringBuffer with StringBuilder
  • Replace String concatenation with append when using StringBuilder/StringBuffer
  • Remove String constructor new String()

I did full builds and fix the errors that pop out.

NetBeans Testing:

  • Full build done (many times)
  • Verify successful execution of libraries and licenses Ant test
  • Verify successful execution of unit tests for all modules inside enterprise and compare the output to the same unit test from master
  • Started NetBeans and ensure the log didn't have any ERROR or new WARNINGS
  • Successfully work with my projects

@pepness pepness added this to the 12.6 milestone Oct 12, 2021
@pepness pepness self-assigned this Oct 12, 2021
@matthiasblaesing
Copy link
Contributor

I have a question about the "Replace length one String in String.indexOf ("c" -> 'c')" part. Are there numbers, that show the char variant is faster or what is the reason for this change?

Copy link
Contributor

@mklaehn mklaehn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like this changeset.
There's two places that were overkill in my opinion (comments added).

@pepness
Copy link
Member Author

pepness commented Oct 18, 2021

I have a question about the "Replace length one String in String.indexOf ("c" -> 'c')" part. Are there numbers, that show the char variant is faster or what is the reason for this change?

I was trusting the Inspect & Transform tool, but now I am testing if this is still true and running some benchmarks. Will update this PR soon and share what I find.

@mbien
Copy link
Member

mbien commented Oct 20, 2021

I have a question about the "Replace length one String in String.indexOf ("c" -> 'c')" part. Are there numbers, that show the char variant is faster or what is the reason for this change?

I was trusting the Inspect & Transform tool, but now I am testing if this is still true and running some benchmarks. Will update this PR soon and share what I find.

indexOf/lastIndexOf are still slightly faster on modern JDKs if chars are used. But there is no difference anymore for StringBuilder.append which is intrinsified and should perform identical in both variants.

For consistency reasons I often default to chars whenever possible - instead of single-char-Strings - so that i don't have to remember the details.

Benchmark                          Mode  Cnt  Score   Error  Units
CharVsStringJMH.appendChar         avgt    5  4.493 ± 0.052  ns/op
CharVsStringJMH.appendString       avgt    5  4.282 ± 0.028  ns/op
CharVsStringJMH.indexOfChar        avgt    5  4.112 ± 0.015  ns/op
CharVsStringJMH.indexOfString      avgt    5  5.333 ± 0.187  ns/op
CharVsStringJMH.lastIndexOfChar    avgt    5  1.979 ± 0.007  ns/op
CharVsStringJMH.lastIndexOfString  avgt    5  2.802 ± 0.038  ns/op
CharVsStringJMH.replaceChar        avgt    5  6.932 ± 0.020  ns/op
CharVsStringJMH.replaceString      avgt    5  6.948 ± 0.045  ns/op

@neilcsmith-net neilcsmith-net modified the milestones: 12.6, NB13 Oct 22, 2021
@matthiasblaesing
Copy link
Contributor

Master is open for changes - it would be good to get this in early. The unittests come back green after a restart.

@mbien
Copy link
Member

mbien commented Nov 7, 2021

regarding the modifications to replace concatenations with append: performance wise, this won't make any differences.

a string concatenation compiled with 8 will directly compile into StringBuilder appends. On 9+ its going to use invokedynamic and java/lang/invoke/StringConcatFactory, which can be even faster. (invoke dynamic is the main reason why recompiling old libs with 9+ can actually make a difference)

for readability reasons and the fact that we shouldn't actually expect any performance gain (we would miss out on the free optimization of StringConcatFactory once NB moved to 9+), i wouldn't recommend making the append changes.

example:

    public String concat2(String a, String b) {
        return a+b;
    }

8

  public java.lang.String concat2(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: new           #7                  // class java/lang/StringBuilder
         3: dup
         4: invokespecial #9                  // Method java/lang/StringBuilder."<init>":()V
         7: aload_1
         8: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        11: aload_2
        12: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        15: invokevirtual #14                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        18: areturn

9+

  public java.lang.String concat2(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: aload_1
         1: aload_2
         2: invokedynamic #7,  0              // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
         7: areturn
      LineNumberTable:
        line 46: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       8     0  this   Ldev/mbien/decompileexperiments/DecompileMe;
            0       8     1     a   Ljava/lang/String;
            0       8     2     b   Ljava/lang/String;
}
SourceFile: "DecompileMe.java"
BootstrapMethods:
  0: #25 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #31 \u0001\u0001
InnerClasses:
  public static final #38= #34 of #36;    // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles

there is also a great talk on that topic https://www.youtube.com/watch?v=z3yu1kjtcok

@mbien
Copy link
Member

mbien commented Nov 7, 2021

as a rule of thumb: Stringbuilder and append should only be used on modern JDKs if the number of concatenations is not known. E.g in loops, recursions etc. For everything else '+' gonna give best results while being also more readable.

The jackpot inspection should be probably revisited at some point. I did update some inspections for 12.6, col.toArray() for example faced a similar issue: it refactored in the wrong direction, now it does the exact opposite it did before :)

@pepness
Copy link
Member Author

pepness commented Nov 12, 2021

Hi, this is the code of my benchmarks, searching inside a string of length 52 and length 101:

package javaperformance;

import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

/**
 *
 * @author pepness
 */
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(3)
public class IndexOfTest {
    
    private String str;
    private char c;
    private String s;
    
    @Setup
    public void setup() {
//        str = " !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; // length 101
        str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; // length 52
        s = "z";
        c = 'z';
    }
    
    @Benchmark
    public int indexOfChar() {
        return str.indexOf('z');
    }
    
    @Benchmark
    public int indexOfString() {
        return str.indexOf("z");
    }
    
    @Benchmark
    public int lastIndexOfChar() {
        return str.lastIndexOf('z');
    }
    
    @Benchmark
    public int lastIndexOfString() {
        return str.lastIndexOf("z");
    }
    
    @Benchmark
    public int indirectIndexOfChar() {
        return str.indexOf(c);
    }
    
    @Benchmark
    public int indirectIndexOfString() {
        return str.indexOf(s);
    }
    
    @Benchmark
    public int indirectLastIndexOfChar() {
        return str.indexOf(c);
    }
    
    @Benchmark
    public int indirectLastIndexOfString() {
        return str.indexOf(s);
    }
    
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(IndexOfTest.class.getSimpleName())
                .threads(1)
                .build();

        new Runner(opt).run();
    }
    
}

These are the results:

JMH version: 1.33
VM version: JDK 1.7.0_322, OpenJDK 64-Bit Server VM, 24.322-b01
VM invoker: /opt/jvm/zulu-7/jre/bin/java

Search inside a string of length 52

Benchmark                              Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar                avgt   30   9.364 ± 0.038  ns/op
IndexOfTest.indexOfString              avgt   30   9.498 ± 0.004  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30   9.939 ± 0.184  ns/op
IndexOfTest.indirectIndexOfString      avgt   30  10.128 ± 0.013  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30   9.788 ± 0.139  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30  10.115 ± 0.002  ns/op
IndexOfTest.lastIndexOfChar            avgt   30   1.707 ± 0.008  ns/op
IndexOfTest.lastIndexOfString          avgt   30   1.695 ± 0.006  ns/op

Search inside a string of length 101

Benchmark                              Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar                avgt   30  14.560 ± 0.050  ns/op
IndexOfTest.indexOfString              avgt   30  14.465 ± 0.016  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30  15.789 ± 0.525  ns/op
IndexOfTest.indirectIndexOfString      avgt   30  15.098 ± 0.048  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30  15.320 ± 0.535  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30  15.104 ± 0.071  ns/op
IndexOfTest.lastIndexOfChar            avgt   30   2.737 ± 0.211  ns/op
IndexOfTest.lastIndexOfString          avgt   30   2.630 ± 0.010  ns/op

VM version: JDK 1.8.0_312, OpenJDK 64-Bit Server VM, 25.312-b07
VM invoker: /opt/jvm/zulu-8/jre/bin/java

Search inside a string of length 52

Benchmark                              Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar                avgt   30   9.555 ± 0.115  ns/op
IndexOfTest.indexOfString              avgt   30   9.548 ± 0.082  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30   9.634 ± 0.114  ns/op
IndexOfTest.indirectIndexOfString      avgt   30  10.173 ± 0.040  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30   9.587 ± 0.081  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30  10.167 ± 0.039  ns/op
IndexOfTest.lastIndexOfChar            avgt   30   1.630 ± 0.010  ns/op
IndexOfTest.lastIndexOfString          avgt   30   1.724 ± 0.007  ns/op

Search inside a string of length 101

Benchmark                              Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar                avgt   30  14.631 ± 0.081  ns/op
IndexOfTest.indexOfString              avgt   30  14.479 ± 0.038  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30  14.696 ± 0.055  ns/op
IndexOfTest.indirectIndexOfString      avgt   30  15.093 ± 0.011  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30  14.772 ± 0.032  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30  15.190 ± 0.065  ns/op
IndexOfTest.lastIndexOfChar            avgt   30   2.509 ± 0.012  ns/op
IndexOfTest.lastIndexOfString          avgt   30   2.642 ± 0.019  ns/op

VM version: JDK 11.0.13, OpenJDK 64-Bit Server VM, 11.0.13+8-LTS
VM invoker: /opt/jvm/zulu-11/bin/java

Search inside a string of length 52

Benchmark                              Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar                avgt   30  10.686 ± 0.224  ns/op
IndexOfTest.indexOfString              avgt   30   6.432 ± 0.023  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30  10.806 ± 0.171  ns/op
IndexOfTest.indirectIndexOfString      avgt   30   8.114 ± 0.131  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30  10.632 ± 0.082  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30   7.837 ± 0.226  ns/op
IndexOfTest.lastIndexOfChar            avgt   30   2.167 ± 0.014  ns/op
IndexOfTest.lastIndexOfString          avgt   30   1.996 ± 0.011  ns/op

Search inside a string of length 101

Benchmark                              Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar                avgt   30  16.409 ± 0.148  ns/op
IndexOfTest.indexOfString              avgt   30   8.459 ± 0.135  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30  16.486 ± 0.357  ns/op
IndexOfTest.indirectIndexOfString      avgt   30   9.302 ± 0.006  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30  16.512 ± 0.327  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30   9.347 ± 0.036  ns/op
IndexOfTest.lastIndexOfChar            avgt   30   3.747 ± 0.013  ns/op
IndexOfTest.lastIndexOfString          avgt   30   3.363 ± 0.027  ns/op

VM version: JDK 17.0.1, OpenJDK 64-Bit Server VM, 17.0.1+12-LTS
VM invoker: /opt/jvm/corretto-17/bin/java

Search inside a string of length 52

Benchmark                              Mode  Cnt  Score   Error  Units
IndexOfTest.indexOfChar                avgt   30  4.113 ± 0.088  ns/op
IndexOfTest.indexOfString              avgt   30  6.413 ± 0.024  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30  3.954 ± 0.022  ns/op
IndexOfTest.indirectIndexOfString      avgt   30  7.657 ± 0.094  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30  3.973 ± 0.021  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30  7.441 ± 0.118  ns/op
IndexOfTest.lastIndexOfChar            avgt   30  2.257 ± 0.043  ns/op
IndexOfTest.lastIndexOfString          avgt   30  1.963 ± 0.017  ns/op

Search inside a string of length 101

Benchmark                              Mode  Cnt  Score   Error  Units
IndexOfTest.indexOfChar                avgt   30  3.585 ± 0.012  ns/op
IndexOfTest.indexOfString              avgt   30  8.270 ± 0.022  ns/op
IndexOfTest.indirectIndexOfChar        avgt   30  3.726 ± 0.029  ns/op
IndexOfTest.indirectIndexOfString      avgt   30  9.152 ± 0.050  ns/op
IndexOfTest.indirectLastIndexOfChar    avgt   30  3.935 ± 0.016  ns/op
IndexOfTest.indirectLastIndexOfString  avgt   30  9.118 ± 0.034  ns/op
IndexOfTest.lastIndexOfChar            avgt   30  3.784 ± 0.019  ns/op
IndexOfTest.lastIndexOfString          avgt   30  3.369 ± 0.024  ns/op

According to my testing (it could be wrong, hope you can test it) when using indexOf/lastIndexOf with chars is up to 53% faster using the latest LTS JDK 17+ but it is slower with previous LTS JDK 11 up to 93%. When using JDK 7 or 8 the performance difference is negligible at least at a length of 101 or less.

If NetBeans is going to be compiled using JDK 11 I would recommend using "c" instead of 'c'.

@mbien
Copy link
Member

mbien commented Nov 12, 2021

@pepness the benchmark looks solid, thanks for sharing. It matches my results too using other JMH benchmarks I wrote once. (I usually have "time" set to 5s instead of 500ms to give the JIT a bit more iterations)

a few remarks:

  • JDK 7 won't play a role for NetBeans since the language level is set to 8, but its still interesting to have the numbers
  • I don't think javac will play a role in this particular case, since it should produce same bytecode for all language levels [1]
    • the differences are due to improvements to fast paths in the JDK and JIT
    • so it basically depends on what JDK NB is running on, not how it was built (in this particular case)
  • the regression on 11 is interesting, my guess is that it has to do with extra logic of compact strings, which is a 9+ feature and took probably a while to get fully optimized
  • its always nice to see how significant the improvement is, caused by a simple JDK upgrade.

My take on this: Since indexof is not dependent on the javac language level, lets optimize for latest JDK versions. The difference is very small but the code difference is tiny too. If 'c' compared to "c" is a little bit faster, its hard to find reasons to not use it.

Even if the performance is going to be equal one day (as it is with replace, append etc), it wouldn't cause a regression either - not in code style or performance.

[1] javac is translating it to standard invokevirtual java/lang/String.indexOf:(Ljava/lang/String;)I or java/lang/String.indexOf:(I)I with no additional invokedynamic magic applied like it would for string concatenations.

You can check this with javap -c -v /path/to/Foo.class (it helps using small classes as input to keep the output smaller)

@mbien
Copy link
Member

mbien commented Nov 12, 2021

results on my system using your benchmark, 52 char string, 5s cycle time.
Looking at it again its not actually a regression in 11, its just that the String version became faster, while the char version remained unchanged. 17 caught up on the char variant while the String version remained unchanged compared to 11.

8
Benchmark                  Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar    avgt   10  18.876 ± 0.335  ns/op
IndexOfTest.indexOfString  avgt   10  14.227 ± 0.231  ns/op
    
11
IndexOfTest.indexOfChar    avgt   10  19.714 ± 0.207  ns/op
IndexOfTest.indexOfString  avgt   10  10.625 ± 0.168  ns/op
    
17
Benchmark                  Mode  Cnt   Score   Error  Units
IndexOfTest.indexOfChar    avgt   10   7.204 ± 0.031  ns/op
IndexOfTest.indexOfString  avgt   10  10.959 ± 0.018  ns/op

@pepness pepness requested a review from mklaehn November 20, 2021 01:12
@mklaehn
Copy link
Contributor

mklaehn commented Nov 21, 2021

looking good. thanks for the changes.
Only problem remaining (from my perspective) are the merge conflicts

Comment on lines -1025 to +1045
getIdBody.append("String params[] = new String[" + params + "];\n" +
"int p = 0;\n" +
"int grabStart = 0;\n" +
"String delim = \"#\";\n" +
"String escape = \"~\";\n" +
"Pattern pattern = Pattern.compile(escape + \"*\" + delim);\n" +
"Matcher matcher = pattern.matcher(string);\n" +
"while (matcher.find()) {\n" +
"String found = matcher.group();\n" +
"if (found.length() % 2 == 1) {\n" +
"params[p] = string.substring(grabStart, matcher.start());\n" +
"p++;\n" +
"grabStart = matcher.end();\n" +
"}\n" +
"}\n" +
"if (p != params.length - 1) {\n" +
"throw new IllegalArgumentException(\"string \" + string + \" is not in expected format. expected " + params + " ids delimited by \" + delim);\n" +
"}\n" +
"params[p] = string.substring(grabStart);\n" +
"for (int i = 0; i < params.length; i++) {\n" +
"params[i] = params[i].replace(escape + delim, delim);\n" +
"params[i] = params[i].replace(escape + escape, escape);\n" +
"}\n\n"
);
getIdBody.append("String params[] = new String[").append(params).append("];\n")
.append("int p = 0;\n")
.append("int grabStart = 0;\n")
.append("String delim = \"#\";\n")
.append("String escape = \"~\";\n")
.append("Pattern pattern = Pattern.compile(escape + \"*\" + delim);\n")
.append("Matcher matcher = pattern.matcher(string);\n")
.append("while (matcher.find()) {\n")
.append("String found = matcher.group();\n")
.append("if (found.length() % 2 == 1) {\n")
.append("params[p] = string.substring(grabStart, matcher.start());\n")
.append("p++;\n")
.append("grabStart = matcher.end();\n")
.append("}\n")
.append("}\n")
.append("if (p != params.length - 1) {\n")
.append("throw new IllegalArgumentException(\"string \" + string + \" is not in expected format. expected ").append(params).append(" ids delimited by \" + delim);\n")
.append("}\n")
.append("params[p] = string.substring(grabStart);\n")
.append("for (int i = 0; i < params.length; i++) {\n")
.append("params[i] = params[i].replace(escape + delim, delim);\n")
.append("params[i] = params[i].replace(escape + escape, escape);\n")
.append("}\n\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not a big fan of those kind of changes. Readability wise, both are similar, but performance wise the original version is going to win. Simple concatenations with constants "foo"+"bar" becomes "foobar" in bytecode anyway, rest is done via invoke dynamic and is likely to be faster than append.

Looking forward, it is also easier to convert concatenations to text blocks in future, which would have a readability gain without performance penalty. Or even later to string templates. append chains are a step back in that regard.

sb.append() is fine for loops or situations where the String structure is not known.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True.

My initial concern was for the readabiility of the automatic cleanup. Future features for the moment are that, future features. Until then my preference is that I'd rather read a multiline version of code/pseudo code like this instead of a single line string hundreds of characters long.

Had we had textblocks available I'd have preferred that even over the current state of the change, but we don't.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so then why change it? Is it a cleanup when there is no improvement in readability while having a performance cost (even though performance doesn't matter at all in this particular case, its not in a inner loop or anything like that).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets agree at least to not run the append refactoring for future cleanups - its a legacy code inspection from java 1.5 times.

But it would be good if the big text block candidates could be reverted back to the original version, so that they can be easier converted in future (NB has a refactoring for that but not for append chains).

Comment on lines -1079 to +1078
getAsStringBody.append(idPropertyType[0] + " id = o." + idGetterName[0] + "();\n" +
"if (id == null) {\n" +
"return \"\";\n" +
"}\n" +
"String delim = \"#\";\n" +
"String escape = \"~\";\n\n"
);
getAsStringBody.append(idPropertyType[0]).append(" id = o.").append(idGetterName[0]).append("();\n")
.append("if (id == null) {\n")
.append("return \"\";\n")
.append("}\n")
.append("String delim = \"#\";\n")
.append("String escape = \"~\";\n\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another example

org.netbeans.modules.schema2beans.BaseBean n;
str.append(indent);
str.append("FileEntry["+this.sizeFileEntry()+"]"); // NOI18N
str.append("FileEntry[").append(this.sizeFileEntry()).append("]"); // NOI18N
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes like this are really unnecessary. Since it would compile to append anyway on 8, and the faster invokedynamic+StringConcatFactory version on 9+. It doesn't improve readability and might reduce performance -> lets not change it ;)

explained here #3241 (comment)

@neilcsmith-net
Copy link
Member

Things that need addressing here so punting to NB14.

@neilcsmith-net neilcsmith-net modified the milestones: NB13, NB14 Jan 17, 2022
pepness and others added 3 commits March 26, 2022 19:57
- Replace length one String in String.indexOf with character
- Remove redundant String.toString()
- Replace String concatenation with '.append' when using StringBuilder
- Remove String constructors
- Remove unnecessary temporary during conversion from String
- Remove unnecessary temporary during conversion to String
- Remove useless use of StringBuffer with StringBuilder
…FClientGenerator.java


Improve readability

Co-authored-by: Martin Klähn <mklaehn@users.noreply.github.com>
…FClientGenerator.java


Improve readability

Co-authored-by: Martin Klähn <mklaehn@users.noreply.github.com>
@pepness pepness force-pushed the cleaning-enterprise-4 branch from 7acf026 to 020d159 Compare March 27, 2022 02:00
@mklaehn
Copy link
Contributor

mklaehn commented Mar 27, 2022

Travis job "Check line endings and verify RAT report" fails on unrelated empty new file enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautConfigCompletionItem.java

@pepness
Copy link
Member Author

pepness commented Mar 29, 2022

Thank you @mklaehn, I mess up the rebase, will keep working on it.

@neilcsmith-net neilcsmith-net modified the milestones: NB14, NB15 Apr 20, 2022
@matthiasblaesing matthiasblaesing modified the milestones: NB15, NB16 Jul 9, 2022
@neilcsmith-net
Copy link
Member

Given this is pushing through milestones without resolution, closing. Please re-open if/when resolved.

@neilcsmith-net neilcsmith-net removed this from the NB16 milestone Oct 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants