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

JDK method:java.lang.Long.numberOfLeadingZeros(long) need to be optimized

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 9
    • core-libs

      A DESCRIPTION OF THE REQUEST :
      the original code is:
      public static int numberOfLeadingZeros(long i) {
              // HD, Figure 5-6
               if (i == 0)
                  return 64;
              int n = 1;
              int x = (int)(i >>> 32);
              if (x == 0) { n += 32; x = (int)i; }
              if (x >>> 16 == 0) { n += 16; x <<= 16; }
              if (x >>> 24 == 0) { n += 8; x <<= 8; }
              if (x >>> 28 == 0) { n += 4; x <<= 4; }
              if (x >>> 30 == 0) { n += 2; x <<= 2; }
              n -= x >>> 31;
              return n;
          }

      I think it can be optimized,should add following condition logic:
      if (i < 0)
              return 0;

      the fully optimized code is:
      public static int numberOfLeadingZeros(long i) {
              // HD, Figure 5-6
               if (i == 0)
                  return 64;
               if (i < 0)
                  return 0;
              int n = 1;
              int x = (int)(i >>> 32);
              if (x == 0) { n += 32; x = (int)i; }
              if (x >>> 16 == 0) { n += 16; x <<= 16; }
              if (x >>> 24 == 0) { n += 8; x <<= 8; }
              if (x >>> 28 == 0) { n += 4; x <<= 4; }
              if (x >>> 30 == 0) { n += 2; x <<= 2; }
              n -= x >>> 31;
              return n;
          }



      JUSTIFICATION :
      In some condition, for example, use -XX:DisableIntrinsic option disabled the intrinsic function, then the default java implementation code will be run. then the original code will be slower than the optimized code.


      ---------- BEGIN SOURCE ----------

      public class TestForNumberOfLeadingZerosOfLong {
          
          public static void main(String[] args) {
              testLong();
          }

          public static void testLong() {
              long startTimeOfOptMethod = System.currentTimeMillis();
              for(long i=-1;i>Integer.MIN_VALUE;i--) {
                  optNumberOfLeadingZeros(i);
              }
              System.out.println("optimized method took time in millis:" + (System.currentTimeMillis() - startTimeOfOptMethod));
              
              long startTimeOfOriginMethod = System.currentTimeMillis();
              for(long i=-1;i>Integer.MIN_VALUE;i--) {
                  Long.numberOfLeadingZeros(i);
              }
              System.out.println("origin method took time in millis:" + (System.currentTimeMillis() - startTimeOfOriginMethod));
          }
          
          public static int optNumberOfLeadingZeros(long i) {
              // HD, Figure 5-6
               if (i == 0)
                  return 64;
               if(i < 0)
                   return 0;
              int n = 1;
              int x = (int)(i >>> 32);
              if (x == 0) { n += 32; x = (int)i; }
              if (x >>> 16 == 0) { n += 16; x <<= 16; }
              if (x >>> 24 == 0) { n += 8; x <<= 8; }
              if (x >>> 28 == 0) { n += 4; x <<= 4; }
              if (x >>> 30 == 0) { n += 2; x <<= 2; }
              n -= x >>> 31;
              return n;
          }
          
      }

      run the test class in cmd line with Intrinsic disabled:
      java -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_numberOfLeadingZeros_l TestForNumberOfLeadingZerosOfLong

      here is the test results from my own MacBook:
      optimized method took time in millis:1510
      origin method took time in millis:4360
      ---------- END SOURCE ----------

            psonal Pallavi Sonal (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: