After reading around on the web it seems to me that nanoTime is more expensive than currentTimeMillis.
For elapsed time measurement, currently the timestamp is only used in three places:
1) Sample.isComplete: now - lastWindow >= config.timeWindowNs
2) SampledState.purgeObsoleteSamples(): now - sample.lastWindow >= expireAge
3) Possibly used on future SampledStat's update/combine functions, currently none of them used the "now" timestamp.
With these use cases I think most measured time spans are large enough for milliseconds.
Another issue I saw is that currently the record() call expose the timestamp input parameter, while the measure() call used the System.nanoTime internally. And we require these two granularities (one used internally and another passed in by users) be consistent. I would prefer to have both of them not exposed to users. If people agree I can go ahead and make these changes.