Mérje meg az eltelt időt Java-ban

1. Áttekintés

Ebben a cikkben megvizsgáljuk, hogyan lehet mérni az eltelt időt a Java-ban. Bár ez könnyen hangozhat, van néhány buktató, amelyekkel tisztában kell lennünk.

Megvizsgáljuk a szokásos Java osztályokat és külső csomagokat, amelyek funkcionalitást nyújtanak az eltelt idő mérésére.

2. Egyszerű mérések

2.1. currentTimeMillis ()

Ha találkozunk az eltelt idő Java-ban történő mérésének követelményével, megpróbálhatjuk ezt megtenni:

hosszú indítás = System.currentTimeMillis (); // ... hosszú befejezés = System.currentTimeMillis (); long timeElapsed = cél - kezdés;

Ha megnézzük a kódot, akkor teljesen logikus. Időbélyeget kapunk az elején, és egy újabb időbélyeget kapunk, amikor a kód elkészül. Az eltelt idő a két érték közötti különbség.

Azonban, az eredmény lehet és pontatlan is lesz System.currentTimeMillis () intézkedéseket falióra idő. A falióra ideje sok okból változhat, pl. a rendszeridő megváltoztatása befolyásolhatja az eredményeket, vagy a szökő másodperc megzavarhatja az eredményt.

2.2. nanoTime ()

Egy másik módszer a java.lang.Rendszer osztály az nanoTime (). Ha megnézzük a Java dokumentációját, a következő állítást találjuk:

"Ez a módszer csak az eltelt idő mérésére használható, és nem kapcsolódik a rendszer vagy a falióra más fogalmához."

Használjuk:

hosszú indítás = System.nanoTime (); // ... hosszú cél = System.nanoTime (); long timeElapsed = cél - start;

A kód alapvetően ugyanaz, mint korábban. Az egyetlen különbség az időbélyegek megszerzésére használt módszer - nanoTime () ahelyett currentTimeMillis ().

Ezt is jegyezzük meg nanoTime ()nyilvánvalóan nanoszekundumokban adja vissza az időt. Ezért, ha az eltelt időt más időegységben mérjük, akkor ennek megfelelően kell átalakítanunk.

Például az ezredmásodpercekre való átváltáshoz el kell osztanunk az eredményt nanoszekundumban 1 000 000-vel.

Újabb buktató nanoTime () az, hogy a Annak ellenére, hogy nanoszekundum pontosságot biztosít, nem garantálja a nanoszekundum felbontást (azaz milyen gyakran frissül az érték).

Ugyanakkor garantálja, hogy a felbontás legalább olyan jó lesz, mint a currentTimeMillis ().

3. Java 8

Ha Java 8-at használunk - kipróbálhatjuk az újat java.time.Instant és java.time.Duration osztályok. Mindkettő változhatatlan, szálbiztos és a saját időskáláját, a Java időskála, akárcsak az új osztály összes osztálya java.time API.

3.1. Java időskála

Az időmérés hagyományos módja az, hogy egy napot 24 órára, 60 perc 60 másodpercre osztunk, ami napi 86.400 másodpercet ad. A nap napjai azonban nem mindig egyformán hosszúak.

Az UTC időskála valójában lehetővé teszi egy nap számára, hogy 86,399 vagy 86,401 SI másodperc legyen. Az SI másodperc egy tudományos „standard nemzetközi másodperc”, amelyet a cézium 133 atomjának sugárzási periódusai határoznak meg). Erre azért van szükség, hogy a nap a Naphoz igazodjon.

A Java időskála minden naptári napot pontosan 86.400 alrészre osztja, amelyek másodpercenként ismertek. Nincsenek ugró másodpercek.

3.2. Azonnali Osztály

A Azonnali osztály egy pillanatot jelent az idővonalon. Alapvetően ez egy numerikus időbélyeg, mivel a Java szokásos korszaka 1970-01-01T00: 00: 00Z.

Az aktuális időbélyeg megszerzéséhez használhatjuk a Instant.now () statikus módszer. Ez a módszer lehetővé teszi az opcionális átadást Óra paraméter. Ha kihagyja, akkor az alapértelmezett időzónában használja a rendszer óráját.

A kezdési és befejezési időket két változóban tárolhatjuk, az előző példákhoz hasonlóan. Ezután kiszámíthatjuk a két pillanat közötti időt.

Ezenkívül használhatjuk a Időtartam osztály és ez között() módszer a kettő közötti időtartam megszerzésére Azonnali tárgyakat. Végül meg kell térnünk Időtartam ezredmásodpercig:

Azonnali indítás = Instant.now (); // KÓD ITT Azonnali befejezés = Instant.now (); long timeElapsed = Duration.between (start, finish) .toMillis ();

4. Stopperóra

A könyvtárakra lépve az Apache Commons Lang biztosítja a Stopperóra osztály, amely az eltelt idő mérésére használható.

4.1. Maven-függőség

A legújabb verziót a pom.xml frissítésével kaphatjuk meg:

 org.apache.commons commons-lang3 3.7 

A függőség legfrissebb verziója itt ellenőrizhető.

4.2. Az eltelt idő mérése a Stopperóra

Először is be kell szereznünk az osztály egy példányát, majd egyszerűen megmérhetjük az eltelt időt:

StopWatch watch = új StopWatch (); watch.start ();

Amint fut egy óra, végre tudjuk hajtani az összehasonlítani kívánt kódot, majd a végén egyszerűen felhívjuk a álljon meg() módszer. Végül a tényleges eredmény elérése érdekében felhívjuk getTime ():

watch.stop (); System.out.println ("Eltelt idő:" + watch.getTime ()); // Nyomatok: Eltelt idő: 2501

Stopperóra rendelkezik néhány további segítő módszerrel, amelyeket a mérés szüneteltetéséhez vagy folytatásához használhatunk. Ez hasznos lehet, ha bonyolultabbá kell tennünk a referenciaértékünket.

Végül jegyezzük meg, hogy az osztály nem biztonságos a szálak számára.

5. Következtetés

Az idő mérésére a Java-ban sokféle lehetőség van. A használat során egy nagyon „hagyományos” (és pontatlan) módszert ismertettünk currentTimeMillis (). Ezenkívül ellenőriztük az Apache Common-okat Stopperóra és megnézte a Java 8-ban elérhető új osztályokat.

Összességében az eltelt idő egyszerű és helyes mérése érdekében a nanoTime () módszer elegendő. Rövidebb a gépelés is, mint currentTimeMillis ().

Megjegyezzük azonban, hogy a megfelelő benchmarkinghoz az idő manuális mérése helyett használhatunk olyan keretrendszert, mint a Java Microbenchmark Harness (JMH). Ez a téma meghaladja a cikk kereteit, de itt feltártuk.

Végül, mint mindig, a vita során használt kód megtalálható a GitHubon.