I wrote a macro that tells the time it takes to complete this operation. He runs it several times and prints the time for each run in nanoseconds. The first launch always takes significantly longer than subsequent ones. Why is this so?
Below are the results of 10 x 10 runs, time Thread.yield():
> (dotimes [x 10] (prn (times 10 (Thread/yield))))
[55395 1659 622 561 591 702 795 719 742 624]
[3255 772 884 677 787 634 605 664 629 657]
[3431 789 965 671 774 767 627 627 521 717]
[2653 780 619 632 616 614 606 602 629 667]
[2373 759 700 676 557 639 659 654 659 676]
[2884 929 627 604 689 614 614 666 588 596]
[2796 749 672 769 667 852 629 589 627 802]
[1308 514 395 321 352 345 411 339 436 315]
[1390 363 328 337 330 321 324 347 333 342]
[1461 416 410 320 414 381 380 388 388 396]
The first run of the first batch is extremely slow, I believe that because of the JIT, which sees the code for the first time, it is fair enough. But the first runs in all subsequent batches are also significantly slower than the following runs. Why?
Macro Code times:
(defmacro time
[expr]
`(let [t1
~expr
(- (System/nanoTime) t1
(defmacro times
[reps expr]
`(loop [reps
(if (zero? reps
times
(recur (dec reps
Decompilation yields the following, so System.nanoTime()it seems to be called immediately before and after Thread.yield(), as intended:
> (decompile (dotimes [x 10] (prn (times 10 (Thread/yield)))))
...
public Object invoke() {
long reps__1952__auto__2355 = 10L;
Object times__1953__auto__2356 = PersistentVector.EMPTY;
while (reps__1952__auto__2355 != 0L) {
final long dec = Numbers.dec(reps__1952__auto__2355);
final IFn fn = (IFn)const__3.getRawRoot();
final Object o = times__1953__auto__2356;
times__1953__auto__2356 = null;
final long t1__1946__auto__2354 = System.nanoTime();
Thread.yield();
times__1953__auto__2356 = fn.invoke(o, Numbers.num(Numbers.minus(System.nanoTime(), t1__1946__auto__2354)));
reps__1952__auto__2355 = dec;
}
final Object o2 = times__1953__auto__2356;
times__1953__auto__2356 = null;
return o2;
}