diff --git a/rules/S3033/java/rule.adoc b/rules/S3033/java/rule.adoc index 0fdaf09320b..c0e553e73b1 100644 --- a/rules/S3033/java/rule.adoc +++ b/rules/S3033/java/rule.adoc @@ -1,31 +1,96 @@ == Why is this an issue? -Assembling a ``++StringBuilder++`` or ``++StringBuffer++`` into a ``++String++`` merely to see if it's empty is a waste of cycles. Instead, jump right to the heart of the matter and get its ``++.length()++`` instead. +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 -[source,java] +[source,java,diff-id=1,diff-type=noncompliant] ---- StringBuilder sb = new StringBuilder(); // ... if ("".equals(sb.toString()) { // Noncompliant // ... } +if (sb.toString().isEmpty()) { // Noncompliant + // ... +} ---- - === Compliant solution -[source,java] +[source,java,diff-id=1,diff-type=compliant] ---- StringBuilder sb = new StringBuilder(); // ... -if (sb.length() == 0) { +if (sb.isEmpty()) { + // ... +} +if (sb.isEmpty()) { // ... } ---- +=== Benchmarks + +[options="header"] +|=== +| Method| Runtime| Average time| Error margin +| isEmpty| Temurin 21| 6.60 ns/op| ±0.58 ns/op +| length| Temurin 21| 6.89 ns/op| ±0.22 ns/op +| toStringEquals| Temurin 21| 10.90 ns/op| ±0.62 ns/op +| toStringIsEmpty| Temurin 21| 11.07 ns/op| ±0.94 ns/op +|=== + + +The results were generated by running the following snippet with https://github.com/openjdk/jmh[JMH]: + +[source,java] +---- +private String[] str = {"a", "b", "c", "d", "e"}; +private StringBuilder sb = new StringBuilder(); + +@Setup(Level.Iteration) +public void setup() { + sb = new StringBuilder(); + for (String s : str) { + sb.append(s); + } +} + +@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(); +} +---- + ifdef::env-github,rspecator-view[]