It is inefficient to build a String
from a StringBuilder
or StringBuffer
just to check if it’s empty.
Instead, directly use the .isEmpty
method.
Noncompliant code example
StringBuilder sb = new StringBuilder();
// ...
if ("".equals(sb.toString()) { // Noncompliant
// ...
}
if (sb.toString().isEmpty()) { // Noncompliant
// ...
}
Compliant solution
StringBuilder sb = new StringBuilder();
// ...
if (sb.isEmpty()) {
// ...
}
if (sb.isEmpty()) {
// ...
}
Benchmarks
Method |
stringBuilderSize |
Runtime |
Average time |
Error margin |
isEmpty |
10 |
Temurin 21 |
6.57 ns/op |
±0.38 ns/op |
isEmpty |
100 |
Temurin 21 |
6.68 ns/op |
±0.10 ns/op |
isEmpty |
1000 |
Temurin 21 |
6.80 ns/op |
±0.12 ns/op |
length |
10 |
Temurin 21 |
6.83 ns/op |
±0.12 ns/op |
length |
100 |
Temurin 21 |
6.66 ns/op |
±0.11 ns/op |
length |
1000 |
Temurin 21 |
6.67 ns/op |
±0.07 ns/op |
toStringEquals |
10 |
Temurin 21 |
13.92 ns/op |
±0.18 ns/op |
toStringEquals |
100 |
Temurin 21 |
59.09 ns/op |
±0.53 ns/op |
toStringEquals |
1000 |
Temurin 21 |
465.79 ns/op |
±5.86 ns/op |
toStringIsEmpty |
10 |
Temurin 21 |
13.83 ns/op |
±0.23 ns/op |
toStringIsEmpty |
100 |
Temurin 21 |
60.06 ns/op |
±3.42 ns/op |
toStringIsEmpty |
1000 |
Temurin 21 |
484.58 ns/op |
±4.24 ns/op |
Benchmarking code
The results were generated by running the following snippet with JMH.
@Param({"10", "100", "1000"})
int stringBuilderSize;
private StringBuilder sb;
@Setup(Level.Iteration)
public void setup() {
sb = new StringBuilder();
IntStream.range(0, stringBuilderSize).forEach(i -> sb.append("word"));
}
@Benchmark
public StringBuilder toStringEquals() {
if ("".equals((sb.toString()))) {
return sb;
}
return new StringBuilder();
}
@Benchmark
public StringBuilder toStringIsEmpty() {
if (sb.toString().isEmpty()) {
return sb;
}
return new StringBuilder();
}
@Benchmark
public StringBuilder length() {
if (sb.length() == 0) {
return sb;
}
return new StringBuilder();
}
@Benchmark
public StringBuilder isEmpty() {
if (sb.isEmpty()) {
return sb;
}
return new StringBuilder();
}