Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8199800

Optimize Boolean.parseBoolean(String)

    XMLWordPrintable

    Details

    • Type: Enhancement
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 11
    • Fix Version/s: 11
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b08

      Description

      Сергей Цыпанов writes:

      https://openjdk.markmail.org/thread/wkdf3df6jkgoutzi

      Hi,

      currently (JDK 9.0.4) j.l.Boolean.valueOf(String) contains this code:

      public static boolean parseBoolean(String s) {
        return ((s != null) && s.equalsIgnoreCase("true"));
      }

      Null check here seems to be redundant, as String.equalsIgnoreCase does it itself:

      public boolean equalsIgnoreCase(String anotherString) {
        return this == anotherString ? true
        : anotherString != null
          && anotherString.length() == length()
          && regionMatches(true, 0, anotherString, 0, length());
      }

      So we can rid this check making

      public static boolean parseBoolean(String s) {
        return "true".equalsIgnoreCase(s));
      }

      which is more simple and faster. Consider benchmark:

      @BenchmarkMode(Mode.AverageTime)
      @OutputTimeUnit(TimeUnit.NANOSECONDS)
      public class EqualsIgnoreCaseBenchmark {

          @Benchmark
          public boolean defaultMethod(Data data) {
              return data.str != null && data.str.equalsIgnoreCase("true");
          }

          @Benchmark
          public boolean betterMethod(Data data) {
              return "true".equalsIgnoreCase(data.str);
          }

          @State(Scope.Thread)
          public static class Data {
              @Param({"true", "false", "null"})
              String str;

              @Setup
              public void setup() {
                  str = "null".equals(str) ? null : str;
              }
          }
      }

      This benchmark on my machine (openjdk version "1.8.0_162", Intel(R) Core(TM) i5-4690) gives the following results:

      Benchmark (str) Mode Cnt Score Error Units
      EqualsIgnoreCaseBenchmark.betterMethod true avgt 50 5.095 ± 0.405 ns/op
      EqualsIgnoreCaseBenchmark.defaultMethod true avgt 50 9.113 ± 0.212 ns/op

      EqualsIgnoreCaseBenchmark.betterMethod false avgt 50 2.973 ± 0.076 ns/op
      EqualsIgnoreCaseBenchmark.defaultMethod false avgt 50 2.842 ± 0.017 ns/op

      EqualsIgnoreCaseBenchmark.betterMethod null avgt 50 2.395 ± 0.020 ns/op
      EqualsIgnoreCaseBenchmark.defaultMethod null avgt 50 2.232 ± 0.020 ns/op

      Also we don't need to do exlicit null check for argument of Boolean.parseBoolean(String) e.g. in jdk.internal.module.ModuleBootstrap, line 302.

      Here's the patch:

      diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java
      --- a/src/java.base/share/classes/java/lang/Boolean.java
      +++ b/src/java.base/share/classes/java/lang/Boolean.java
      @@ -129,7 +129,7 @@
            * @since 1.5
            */
           public static boolean parseBoolean(String s) {
      - return ((s != null) && s.equalsIgnoreCase("true"));
      + return "true".equalsIgnoreCase(s);
           }

           /**
      @@ -238,7 +238,7 @@
            */
           public boolean equals(Object obj) {
               if (obj instanceof Boolean) {
      - return value == ((Boolean)obj).booleanValue();
      + return value == (Boolean) obj;
               }
               return false;
           }
      diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
      --- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
      +++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
      @@ -299,7 +299,7 @@

               PrintStream traceOutput = null;
               propValue = getAndRemoveProperty("jdk.module.showModuleResolution");
      - if (propValue != null && Boolean.parseBoolean(propValue))
      + if (Boolean.parseBoolean(propValue))
                   traceOutput = System.out;

               // run the resolver to create the configuration


      Regards,
      Sergey Tsypanov

        Attachments

          Activity

            People

            Assignee:
            martin Martin Buchholz
            Reporter:
            martin Martin Buchholz
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: