1.7 以納秒級(jí)的時(shí)間計(jì)算:使用System.nanoTime
Java5+
摩爾定律是一種眾所周知的現(xiàn)象,即計(jì)算機(jī)中的晶體管數(shù)量和它的處理速度隨時(shí)間呈指數(shù)規(guī)律增長(zhǎng)。作為仙童半導(dǎo)體公司(Fairchild Semiconductor)的研發(fā)領(lǐng)導(dǎo)人,戈登?摩爾于1965年提出了這一偉大發(fā)現(xiàn)。迄今為止,它仍有效。
與
Java首次出現(xiàn)的時(shí)候相比,當(dāng)前計(jì)算機(jī)的速度要快得多,對(duì)于很多應(yīng)用程序而言以毫秒計(jì)時(shí)已不再能夠滿足要求。你可能使用過(guò)
java.lang.System類,利用currentTimeMillis方法來(lái)獲得一個(gè)方法調(diào)用或一段代碼的定時(shí)信息。此方法可以用來(lái)度量執(zhí)行某操
作所花費(fèi)的時(shí)間。但是,在運(yùn)算速度更快的計(jì)算機(jī)上操作花費(fèi)的時(shí)間可能遠(yuǎn)小于1毫秒,于是可以在一個(gè)for循環(huán)中執(zhí)行此操作上百次或上千次,然后除以循環(huán)次
數(shù)來(lái)計(jì)算此操作的單位時(shí)間??紤]下面的示例:
long startTime = System.currentTimeMillis(); for (int i=0; i<1000; i++) { performOperation(); // something we want to measure } long endTime = System.currentTimeMillis(); long totalTimeInMillis = endTime - startTime; // because the count was 1000, it's easy to get the unit time long unitTimeInMicros = totalTimeInMillis;
|
這種一種很簡(jiǎn)單的運(yùn)算,因?yàn)槭褂昧薴or循環(huán)1000次。但是如果要度量亞微秒該如何實(shí)現(xiàn)呢?
for(int i=0; i<1000000; i++) { performOperation(); }
|
如
果從人類的角度來(lái)看,可憐的for循環(huán)將不得不不厭其煩地百萬(wàn)次的頻繁循環(huán)!此外,只有在重復(fù)執(zhí)行操作沒有副作用的情況下使用for循環(huán)來(lái)計(jì)算時(shí)間才是有
用的。如果操作是調(diào)用java.util.Collections.sort方法,那么將很難計(jì)算出排序過(guò)程花費(fèi)的時(shí)間。在Java
5中,System類有一個(gè)新的nanoTime方法,它能返回一個(gè)納秒精度的計(jì)數(shù)器。盡管不能將它用于度量絕對(duì)時(shí)間,但是它能夠很好地度量時(shí)間差別。
List myList = initializeList(); // initialize the List somehow long startTime = System.nanoTime(); Collections.sort(myList); // measuring the sort time long endTime = System.nanoTime(); long differenceInNanoseconds = endTime - startTime;
|
遺憾的是,運(yùn)行上面的代碼時(shí)無(wú)法保證實(shí)際上獲得的是納秒級(jí)的度量。但是使用更快的機(jī)器和良好的JRE實(shí)現(xiàn),對(duì)于測(cè)試目的而言它是一種有用的度量方
法??梢栽贘DK
5文檔中找到更多有關(guān)此方法的信息。鑒于操作系統(tǒng)特性、機(jī)器處理速度和系統(tǒng)負(fù)載的不同,得到的由nanoTime方法返回的值可能會(huì)有很大的變化。隨著時(shí)
間的推移此問(wèn)題應(yīng)該會(huì)有所改善,摩爾定律基本上能保證這一點(diǎn)。