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 ----------
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 ----------
- duplicates
-
JDK-8189230 JDK method:java.lang.Integer.numberOfLeadingZeros(int) can be optimized
-
- Resolved
-