कैसे जावा कार्यक्रम निष्पादन की गति के लिए समय


85

आप एक जावा कार्यक्रम के निष्पादन में कैसे समय लेते हैं? मुझे यकीन नहीं है कि मुझे ऐसा करने के लिए किस वर्ग का उपयोग करना चाहिए।

मैं थोड़े चाह रहा हूँ जैसे:

// Some timer starts here
for (int i = 0; i < length; i++) {
  // Do something
}
// End timer here

System.out.println("Total execution time: " + totalExecutionTime);

जवाबों:


139
final long startTime = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
  // Do something
}
final long endTime = System.currentTimeMillis();

System.out.println("Total execution time: " + (endTime - startTime));

2
यह वास्तव में नैनोमीटर होना चाहिए
यूजीन

6
नैनो टाइम नहीं होना चाहिए। देखिये राहू का जवाब
फेबस्प्रो

4
क्या कुछ विशेष कारण है जो आपने "अंतिम" का उपयोग किया है? यदि आप उस कीवर्ड को गिरा देते हैं, तो क्या होगा?
dijxtra

9
@dijxtra का उपयोग करने finalसे यह फायदा होता है कि आप गलती से इसे असाइन नहीं कर सकते हैं (साथ ही अन्य फायदे, जैसे कि अनाम वर्ग की पहुंच आदि)। इस कोड में इससे कोई फर्क नहीं पड़ेगा। यह सब कुछ बनाने के लिए एक बहुत ही सामान्य अभ्यास है finalऔर finalयदि आप की जरूरत है तो केवल इसे ize।
wchargin

1
समय मापन के साथ-साथ परीक्षण किए जाने वाले कोड को कई बार चलाया जाना चाहिए और पहले परिणाम को छोड़ देना चाहिए। पहले संभावित रूप से क्लास लोडिंग समय आदि शामिल होंगे। इसे कई बार चलाने से भी आपको औसत मिलेगा जो अधिक सहायक और विश्वसनीय है।
अरुण रामकृष्णन

34

ध्यान रखें कि कुछ ऐसे मुद्दे हैं, जिनका System#nanoTime()बहु-सीपीयू सीपीयू पर रिकॉर्ड किए गए समय को रिकॉर्ड करने के लिए मज़बूती से उपयोग नहीं किया जा सकता है ... प्रत्येक कोर ने अपना टीएससी ( टाइम स्टैम्प काउंटर ) बनाए रखा है : इस काउंटर का उपयोग नैनो समय प्राप्त करने के लिए किया जाता है (वास्तव में यह है) सीपीयू बूट होने के बाद से टिक की संख्या)।

इसलिए, जब तक कि कोर को सिंक में रखने के लिए OS कुछ TSC का समय नहीं देता, तब यदि प्रारंभिक समय पढ़ने पर एक धागा एक कोर पर अनुसूचित हो जाता है, तो एक अलग कोर में स्विच किया जाता है, सापेक्ष समय छिटपुट रूप से आगे की ओर कूदने के लिए प्रकट हो सकता है और आगे की ओर।

मैंने इसे कुछ समय पहले एएमडी / सोलारिस पर देखा था, जहां दो टाइमिंग पॉइंट्स के बीच का समय कभी-कभी नकारात्मक मूल्यों या अप्रत्याशित रूप से बड़े सकारात्मक नंबरों के रूप में वापस आ रहा था। AMD SolarNow को मजबूर करने के लिए सोलारिस कर्नेल पैच और एक BIOS सेटिंग की आवश्यकता थी! बंद, जो इसे हल करने के लिए दिखाई दिया।

इसके अलावा, वहाँ (एएफएआईके) System#nanoTime()एक वर्चुअलबॉक्स वातावरण में जावा का उपयोग करते समय एक बहुत दूर का बग है; java.util.concurrencyपैकेज के रूप में ज्यादा के रूप में हमारे लिए विचित्र आंतरायिक सूत्रण समस्याओं के सभी प्रकार के कारण नैनो समय पर निर्भर करता है।

यह सभी देखें:

क्या System.nanoTime () पूरी तरह से बेकार है? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html


9

आपको मिलीसेकंड में वर्तमान सिस्टम समय मिलता है:

final long startTime = System.currentTimeMillis();

फिर तुम वही करो जो तुम करने जा रहे हो:

for (int i = 0; i < length; i++) {
  // Do something
}

फिर आप देखें कि इसमें कितना समय लगा:

final long elapsedTimeMillis = System.currentTimeMillis() - startTime;

BalusC का उत्तर भी सही है; यह आवश्यक टाइमर रिज़ॉल्यूशन पर निर्भर करता है, और आपको समय की आवश्यकता क्यों है।
जोनाथन फीनबर्ग

9

आप का उपयोग कर सकते System#nanoTime()। निष्पादन से पहले और बाद में प्राप्त करें और बस गणित करें। यह ऊपर पसंद किया जाता है System#currentTimeMillis()क्योंकि इसमें एक बेहतर परिशुद्धता है। हार्डवेयर और उपयोग किए गए प्लेटफॉर्म के आधार पर, आप अन्यथा बीते हुए समय में गलत अंतर पा सकते हैं। विंडोज पर Core2Duo के साथ, लगभग 0 और ~ 15ms के बीच वास्तव में कुछ भी गणना नहीं की जा सकती है।

एक अधिक उन्नत उपकरण एक प्रोफाइलर है


विंडोज पर टाइमर में डिफ़ॉल्ट रूप से विशेष रूप से अच्छा रिज़ॉल्यूशन नहीं है। वहाँ है एक उच्च प्रदर्शन टाइमर भी है, लेकिन यह बहुत कठिन है सी से भी उपयोग करने के लिए और जावा (AFAIK) है कि कम एक JNI बिना hackery का एक स्तर thunk के लिए उपयोग नहीं प्रदान करता है।
डोनल फैलो

1
nanoTime()एक समस्या है (कम से कम विंडोज पर); टाइमस्टैम्प प्रोसेसर कोर के लिए विशिष्ट है। मेरे पास एक कार्यक्रम था जिसे नकारात्मक निष्पादन का समय मिला क्योंकि इसे एक कोर पर "स्टार्ट" टाइमस्टैम्प मिला, और दूसरे कोर पर "स्टॉप" टाइमस्टैम्प।
gustafc

3

सरल सामान के लिए, System.currentTimeMillis () काम कर सकता है।

यह वास्तव में इतना सामान्य है कि मेरा आईडीई सेटअप है ताकि "t0" में प्रवेश करने पर यह मुझे निम्नलिखित पंक्ति उत्पन्न करे:

final long t0 = System.currentTimeMillis()

लेकिन अधिक जटिल चीजों के लिए, आप शायद सांख्यिकीय समय मापन का उपयोग करना चाहते हैं, जैसे यहां (थोड़ा नीचे स्क्रॉल करें और मानक विचलन सहित व्यक्त किए गए समय मापों को देखें):

http://perf4j.codehaus.org/devguide.html


ऑटो-जनरेटर कोड को इंगित करने के लिए +1। मैं हर समय एक जैसे कथन का उपयोग करता हूं, और कोड टेम्प्लेट डालने के बारे में नहीं जानता। बस यह पता चला कि ग्रहण के साथ ऐसा कैसे करें, और यह निश्चित रूप से मदद करेगा!
जेसन

सभी Codehaus सेवाओं को समाप्त कर दिया गया है। आपका लिंक अब टूट गया है
naXa

2

AOP / AspectJ और जेकबी-पहलुओं@Loggable से एनोटेशन का उपयोग करके आप इसे आसान और कॉम्पैक्ट कर सकते हैं:

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

इस पद्धति की प्रत्येक कॉल को DEBUGलॉगिंग स्तर के साथ SLF4J लॉगिंग सुविधा में भेजा जाएगा । और हर लॉग संदेश में निष्पादन समय शामिल होगा।


2

जावा में निष्पादन समय खोजने के कुछ तरीके यहां दिए गए हैं:

1) System.nanoTime ()

long startTime = System.nanoTime();
.....your code....
long endTime   = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in nanoseconds  : " + totalTime);
System.out.println("Execution time in milliseconds : " + totalTime / 1000000);

2) System.currentTimeMillis ()

long startTime = System.currentTimeMillis();
.....your code....
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds  : " + totalTime);

3) झटपट। अनजान ()

long startTime = Instant.now().toEpochMilli();
.....your code....
long endTime = Instant.now().toEpochMilli();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

या

Instant start = Instant.now();
.....your code....
Instant end = Instant.now();
Duration interval = Duration.between(start, end);
System.out.println("Execution time in seconds: " +interval.getSeconds());

4) दिनांक.getTime ()

long startTime = new Date().getTime();
.....your code....
long endTime = new Date().getTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

1

startTime=System.currentTimeMillis()लूप के शीर्ष पर, प्रारंभ समय के लिए लंबे समय तक उपयोग करें

long endTime= System.currentTimeMillis();लूप के अंत के बाहर डाल दिया । मिलीसेकंड में रनटाइम प्राप्त करने के लिए आपको मूल्यों को घटाना होगा।

यदि आप नैनोसेकंड में समय चाहते हैं, तो जांचें System.nanoTime()


1

मैंने एक उच्च क्रम फ़ंक्शन बनाया जो कोड को एक लैम्ब्डा के रूप में / में मापना चाहता है:

class Utils {

    public static <T> T timeIt(String msg, Supplier<T> s) {
        long startTime = System.nanoTime();
        T t = s.get();
        long endTime = System.nanoTime();
        System.out.println(msg + ": " + (endTime - startTime) + " ns");
        return t;
    }

    public static void timeIt(String msg, Runnable r) {
       timeIt(msg, () -> {r.run(); return null; });
    }
}

इसे इस तरह से कॉल करें:

Utils.timeIt("code 0", () ->
        System.out.println("Hallo")
);

// in case you need the result of the lambda
int i = Utils.timeIt("code 1", () ->
        5 * 5
);

आउटपुट:

कोड 0: 180528 एनएस
कोड 1: 12003 एनएस

एंडी टर्नर के लिए विशेष धन्यवाद जिन्होंने मुझे अतिरेक में कटौती करने में मदद की। देखें यहाँ



0

आप Perf4J भी आज़मा सकते हैं। इसका एक साफ-सुथरा तरीका है कि आप क्या देख रहे हैं, और एक निर्धारित समय अवधि में प्रति सेकंड, न्यूनतम, अधिकतम, मानक विचलन और लेनदेन जैसे समेकित प्रदर्शन आंकड़ों में मदद करता है। Http://perf4j.codehaus.org/devguide.html से एक उद्धरण :

StopWatch stopWatch = new LoggingStopWatch();

try {
    // the code block being timed - this is just a dummy example
    long sleepTime = (long)(Math.random() * 1000L);
    Thread.sleep(sleepTime);
    if (sleepTime > 500L) {
        throw new Exception("Throwing exception");
    }

    stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
    stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}

आउटपुट:

INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]

0
public class someClass
{
   public static void main(String[] args) // your app start point
   {
       long start = java.util.Calendar.getInstance().getTimeInMillis();

       ... your stuff ...

       long end = java.util.Calendar.getInstance().getTimeInMillis();
       System.out.println("it took this long to complete this stuff: " + (end - start) + "ms");
   }
}

0

System.currentTimeMillis () का उपयोग करना ऐसा करने का उचित तरीका है। लेकिन, यदि आप कमांड लाइन का उपयोग करते हैं, और आप पूरे कार्यक्रम को लगभग और जल्दी से समय देना चाहते हैं, तो इसके बारे में सोचें:

time java App

जो आपको अपने ऐप के कोड और समय को संशोधित करने की अनुमति नहीं देता है।


यह इस बात पर निर्भर करता है कि आप कोड कैसे चलाते हैं। यदि यह सर्वर चलाने वाले कोड का एक टुकड़ा है, तो आप स्टार्टअप समय को शामिल करने जा रहे हैं जो कि गलत है।
अरुण रामकृष्णन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.