FULL PRODUCT VERSION :
java version "1.8.0_162-ea"
Java(TM) SE Runtime Environment (build 1.8.0_162-ea-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b01, mixed mode)
FULL OS VERSION :
Microsoft Windows [Version 10.0.16299.19]
A DESCRIPTION OF THE PROBLEM :
When I have a string(s) passed in as a parameter to a function and use < parseInt(s) as a loop terminating condition, it's more than 2x slower compared to storing it in a local variable and looping. This is a small variation I was playing with when testing for bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8191016 which is also reported by me.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just compile and run the class attached below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected the 'time taken' value to be close to equal on all 10 lines. Instead I get loop condition with function call more than 2x slower.
C:\Users\srviswan\Downloads\c#-test>java -server CsTest 1000000
X: 499990; Time taken: 43ms.
X: 500097; Time taken with NO parseInt: 17ms.
X: 499825; Time taken: 42ms.
X: 500094; Time taken with NO parseInt: 15ms.
X: 500012; Time taken: 28ms.
X: 499852; Time taken with NO parseInt: 15ms.
X: 500232; Time taken: 32ms.
X: 499904; Time taken with NO parseInt: 13ms.
X: 499972; Time taken: 29ms.
X: 500124; Time taken with NO parseInt: 15ms.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class CsTest {
private int caught = 0;
private boolean x;
private final java.util.Random r = new java.util.Random();
public final boolean f() { x = false; return !g() && !x; }
public final boolean g() { return h(); }
public final boolean h() { if ((r.nextInt() & 1) == 1) {x = true;return true; } return false; }
public static void main(final String[] args) throws Throwable {
test(args[0]);
}
private static void test(final String arg) throws Throwable {
final CsTest t = new CsTest();
final String s = arg;
for (int j = 0; j < 5; j++) {
int x = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < Integer.parseInt(s); i++) if (t.f()) x++;
System.err.println("X: " + x + "; Time taken: " + (System.currentTimeMillis() - start) + "ms.");
x = 0
final long l = Integer.parseInt(s);
start = System.currentTimeMillis();
for (int i = 0; i < l; i++) if (t.f()) x++;
System.err.println("X: " + x + "; Time taken with NO parseInt: " + (System.currentTimeMillis() - start) + "ms.");
}
}
}
---------- END SOURCE ----------
java version "1.8.0_162-ea"
Java(TM) SE Runtime Environment (build 1.8.0_162-ea-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b01, mixed mode)
FULL OS VERSION :
Microsoft Windows [Version 10.0.16299.19]
A DESCRIPTION OF THE PROBLEM :
When I have a string(s) passed in as a parameter to a function and use < parseInt(s) as a loop terminating condition, it's more than 2x slower compared to storing it in a local variable and looping. This is a small variation I was playing with when testing for bug: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8191016 which is also reported by me.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just compile and run the class attached below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected the 'time taken' value to be close to equal on all 10 lines. Instead I get loop condition with function call more than 2x slower.
C:\Users\srviswan\Downloads\c#-test>java -server CsTest 1000000
X: 499990; Time taken: 43ms.
X: 500097; Time taken with NO parseInt: 17ms.
X: 499825; Time taken: 42ms.
X: 500094; Time taken with NO parseInt: 15ms.
X: 500012; Time taken: 28ms.
X: 499852; Time taken with NO parseInt: 15ms.
X: 500232; Time taken: 32ms.
X: 499904; Time taken with NO parseInt: 13ms.
X: 499972; Time taken: 29ms.
X: 500124; Time taken with NO parseInt: 15ms.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class CsTest {
private int caught = 0;
private boolean x;
private final java.util.Random r = new java.util.Random();
public final boolean f() { x = false; return !g() && !x; }
public final boolean g() { return h(); }
public final boolean h() { if ((r.nextInt() & 1) == 1) {x = true;return true; } return false; }
public static void main(final String[] args) throws Throwable {
test(args[0]);
}
private static void test(final String arg) throws Throwable {
final CsTest t = new CsTest();
final String s = arg;
for (int j = 0; j < 5; j++) {
int x = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < Integer.parseInt(s); i++) if (t.f()) x++;
System.err.println("X: " + x + "; Time taken: " + (System.currentTimeMillis() - start) + "ms.");
x = 0
final long l = Integer.parseInt(s);
start = System.currentTimeMillis();
for (int i = 0; i < l; i++) if (t.f()) x++;
System.err.println("X: " + x + "; Time taken with NO parseInt: " + (System.currentTimeMillis() - start) + "ms.");
}
}
}
---------- END SOURCE ----------