You're absolutely correct! It doesn't seem to count in smaller than 15 or 16 ms.
(defun test
-time
(run var func
/ val result
) result
(if (= (caar result
) val
) result
Then this produces a list containing items in the following format:
(<returned-value> <difference-from-previous> <repeated-same-value-count>)
_$ (test-time 10000 'millisecs (function (lambda (v) v)))
((15712358 16 926) (15712342 15 1858) (15712327 16 2985) (15712311 16 2841))
_$ (test-time 1000 'date (function (lambda (v) (fix (rem (* v 1000000000.0) 2147483648.0)))))
((1380298545 12 153) (1380298533 12 155) (1380298521 11 156) (1380298510 11 154) (1380298499 12 156) (1380298487 12 156))
_$ (test-time 100 'cputicks (function (lambda (v) v)))
((4.23054e+013 12643.0 1) (4.23054e+013 12646.0 1) (4.23054e+013 12388.0 1) (4.23054e+013 12237.0 1) (4.23054e+013 12360.0 1) (4.23054e+013 12443.0 1) (4.23054e+013 14265.0 1) (4.23054e+013 12240.0 1) (4.23054e+013 12335.0 1) (4.23054e+013 12249.0 1) (4.23054e+013 12486.0 1) (4.23054e+013 12413.0 1) (4.23054e+013 12766.0 1) (4.23054e+013 12317.0 1)...
It seems using the date sysvar gives a slightly more finer grained difference. MilliSecs between 15 and 16 ms, and Date between 11 and 12. Obviously cputicks are much more fine grained - but then you get into the scenario where one PC's cputicks are different from another's.
What you could try though is to test a CPU's speed and then apply the average around that:
(defun CpuHertz
(/ time ticks
) (/ (- (getvar 'cputicks
) ticks
) 1e0
))
(setq *cputick
-time
* nil) (defun getSecondsTimer
(/ time prev
) (* *cputick
-time
* (getvar 'cputicks
)) (progn (setq *cputick
-time
* (/ 1.0 (CpuHertz
))) (getSecondsTimer
))))
So now it would measure the clockspeed of the cpu on first use, thereafter it will convert the cputicks to a real value in seconds. It seems very fine grained in deed
_$ (test-time 500 'date (function (lambda (v) (fix (rem (* (getSecondsTimer) 1000.0) 2147483648.0)))))
((17538368 1 22) (17538367 1 124) (17538366 1 123) (17538365 1 126))
So definitely better than 1 ms. Actually a cputick would be the 1sec / Hz, which on my CPU (2.67GHz) would equal 0.0000000003745318 sec or 0.374532 nano seconds (ns).
But the testing itself is taking up some time (especially when you now get into this infinitesimal period):
_$ (test-time 5 'date (function (lambda (v) (fix (rem (* (getSecondsTimer) 1000000.0) 2147483648.0)))))
((385220994 8 1) (385220986 8 1) (385220978 7 1) (385220971 12 1))
So the test itself takes around 7 to 12 micro seconds (μs), or 7000ns to 12000ns, or thus between 18000 and 32000 cputicks. Of course you're also getting a bit of floating point errors in that.