This happens because your "no thread" (only main thread) version uses all compile time constants which are easier to optimize.
If you make sure the compiler won't know ahead of time what the values will be:
class Main{
public static void main(String args[]) {
long factorial = Long.parseLong(args[0]);
long modulo = Long.parseLong(args[1]);
long startTime = System.nanoTime();
long res = 1;
for(long i = 1; i <= factorial; i++) {
res *= i;
res %= modulo;
}
System.out.println(res);
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println((double)totalTime/1000000000L);
}
}
Then it'll be significantly slower:
$ java Main 1000000000 1000000007
698611116
11.368487148
On my machine, even slightly more so than the 1-thread case of your other one:
$ java Main
698611116
10.709532315
Similarly, if you modify your 1-thread example to use .run()
instead of .start()
, everything will run on the main thread, but there will be no speedup from the 1-thread case.