शेल में प्रोग्राम निष्पादन समय प्राप्त करें


407

मैं कुछ अलग परिस्थितियों में एक लिनक्स शेल में कुछ निष्पादित करना चाहता हूं, और प्रत्येक निष्पादन के निष्पादन समय को आउटपुट करने में सक्षम हूं।

मुझे पता है कि मैं एक पर्ल या पाइथन स्क्रिप्ट लिख सकता हूं जो ऐसा करेगी, लेकिन क्या कोई तरीका है जो मैं इसे शेल में कर सकता हूं? (जो होता है बैश)


2
विंडोज केस: stackoverflow.com/questions/673523/…
n611x007

क्या Ticksखिड़कियों के मामले की तरह यह संभव है ?
२४:४४ पर १४

जवाबों:


534

अंतर्निहित timeकीवर्ड का उपयोग करें :

$ सहायता समय

समय: समय [-पी] पाइपलाइन
    PIPELINE निष्पादित करें और वास्तविक समय, उपयोगकर्ता CPU समय का सारांश प्रिंट करें,
    और सिस्टम CPU समय समाप्त होने पर PIPELINE को निष्पादित करने में खर्च होता है।
    वापसी की स्थिति PIPELINE की वापसी स्थिति है। `-P’ विकल्प
    समय सारांश को थोड़े अलग प्रारूप में प्रिंट करता है। यह उपयोग करता है
    आउटपुट प्रारूप के रूप में TIMEFORMAT चर का मान।

उदाहरण:

$ time sleep 2
वास्तविक 0m2.009s
उपयोगकर्ता 0m0.000s
sys 0m0.004s

1
यह एक कमांड पर कैसे उपयोग किया जाता है time -p i=x; while read line; do x=x; done < /path/to/file.txt? यह तुरंत 0.00 रिटर्न करता है जब तक कि मैं लूप से पहले कुछ भी नहीं डालूं .. क्या देता है?
नटली

यह खराब 'समय' संस्करण है, बैश बिलिन। बाहरी 'समय' कहां है?
ज़निक

6
@Znik, कोशिश / usr / बिन / समय
मार्क राजकोक

10
@ नटली: जबकि timeएक पूरी पाइपलाइन को समय के अनुसार (बैश कीवर्ड होने के आधार पर ), आपको कई कमांड के लिए एक ग्रुप कमांड ( { ...; ...; }) से समय का उपयोग करने की आवश्यकता है :time -p { i=x; while read line; do x=x; done < /path/to/file.txt; }
mklement0

2
समय के सभी संस्करणों आप अपने सिस्टम पर स्थापित किया है देखने के लिए, आप उपयोग कर सकते हैंtype -a time
spinup

120

आप समय (1)time का उपयोग करके बने बैश-इन (जो रॉबर्ट गैंबल का उल्लेख करते हैं) की तुलना में अधिक विस्तृत जानकारी प्राप्त कर सकते हैं । आम तौर पर यह है ।/usr/bin/time

संपादक का ध्यान दें: यह सुनिश्चित करने के लिए कि आप अपने शेल के कीवर्ड के बजाय बाहरी उपयोगिता को लागू कर रहे हैं , इसे लागू करें । एक है POSIX द्वारा आदेशित उपयोगिता है, लेकिन एकमात्र विकल्प यह समर्थन करने के लिए आवश्यक है । विशिष्ट प्लेटफ़ॉर्म विशिष्ट, गैर-मानक एक्सटेंशन को लागू करते हैं: GNU के साथ काम करता हैtimetime /usr/bin/time
time-p
-v की timeउपयोगिता के , जैसा कि नीचे दिखाया गया है (प्रश्न टैग किया गया है); BSD / macOS कार्यान्वयन -lसमान उत्पादन के लिए उपयोग करता है - देखें man 1 time

वर्बोज़ आउटपुट का उदाहरण:


$ /usr/bin/time -v sleep 1
       Command being timed: "sleep 1"
       User time (seconds): 0.00
       System time (seconds): 0.00
       Percent of CPU this job got: 1%
       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
       Average shared text size (kbytes): 0
       Average unshared data size (kbytes): 0
       Average stack size (kbytes): 0
       Average total size (kbytes): 0
       Maximum resident set size (kbytes): 0
       Average resident set size (kbytes): 0
       Major (requiring I/O) page faults: 0
       Minor (reclaiming a frame) page faults: 210
       Voluntary context switches: 2
       Involuntary context switches: 1
       Swaps: 0
       File system inputs: 0
       File system outputs: 0
       Socket messages sent: 0
       Socket messages received: 0
       Signals delivered: 0
       Page size (bytes): 4096
       Exit status: 0


2
आपको यह पता नहीं होगा कि डेबियन पैकेज क्या होगा? द्वारा डिफ़ॉल्ट स्थापित किया जाना प्रतीत नहीं होता है
ʞɔıu

1
मैं आपकी पोस्ट रॉबर्ट का जिक्र कर रहा था। जब तक आप का अर्थ है कि आपके द्वारा सुझाई गई कमांड बैश बिल्ट-इन नहीं है?
grepsedawk

24
आश्चर्यजनक रूप से पर्याप्त है, इसे "समय" नामक पैकेज से स्थापित किया गया है।
पॉल टॉम्बलिन

2
की तरह / usr / bin / समय दिखता से उत्पादन: "0.00user 0.00system 0 02.00elapsed 0% सीपीयू (0avgtext + 0avgdata 0maxresident) कश्मीर 0inputs + 0outputs (0major + 172minor) pagefaults 0swaps"
पॉल Tomblin

4
@ निक: "sudo apt-get install time"।
रॉबर्ट गैंबल

79
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

14
बहुत सरल तरीका है। बैश स्वचालित रूप से विशेष चर $ SECONDS की गणना करते हैं, फिर बाह्य तिथि कमांड के आधार पर पुनर्गणना अनावश्यक है। $ SECONDS चर शुरू होने पर कितने सेकंड बैश स्क्रिप्ट चल रहा है। इस चर में कुछ विशेष गुण हैं। मैन पेज देखें: D
Znik

मैंने टिप्पणी में उपरोक्त और विधि दोनों की कोशिश की है। 1 में मुझे एक 'अवैध चर' त्रुटि मिलती है और दूसरे को मुझे 'अज्ञात चर' मिलता है
DrBwts

45

एक लाइन-बाय-लाइन डेल्टा माप के लिए, सूक्ति का प्रयास करें ।

एक कमांड लाइन उपयोगिता, थोडा और अधिक टीटीएस की तरह, टाइमस्टैम्प जानकारी को दूसरे कमांड के मानक आउटपुट के लिए तैयार करने के लिए। लंबे समय तक चलने वाली प्रक्रियाओं के लिए उपयोगी है जहाँ आप इतना लंबा समय ले रहे हैं का एक ऐतिहासिक रिकॉर्ड चाहते हैं।

आप सेकंड में एक लंबाई सीमा निर्दिष्ट करने के लिए --highऔर / या --mediumविकल्पों का उपयोग कर सकते हैं , जिस पर सूक्ति लाल या पीले रंग में टाइमस्टैम्प को उजागर करेगा। और आप कुछ अन्य चीजें भी कर सकते हैं।

उदाहरण


3
महान टिप, लेकिन सिर्फ स्पष्ट होने के लिए: यह लाइन-बाय-लाइन टाइमिंग के लिए उपयोगी है , लेकिन इस तरह के ठीक-ठीक समय लेने का ओवरहेड समग्र समय में महत्वपूर्ण रूप से जोड़ता है ।
mklement0

2
विस्मयकारी उपयोगिता .. साझा करने के लिए धन्यवाद
किशन बी

19

आप और अधिक सटीक, उपयोग के इच्छुक हों %Nके साथ date(और उपयोग bcdiff के लिए है, क्योंकि $(())केवल पूर्णांकों संभालती है)।

यह कैसे करना है:

start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)

printf "Execution time: %.6f seconds" $dur

उदाहरण:

start=$(date +%s.%N); \
  sleep 0.1s; \
  dur=$(echo "$(date +%s.%N) - $start" | bc); \
  printf "Execution time: %.6f seconds\n" $dur

परिणाम:

Execution time: 0.104623 seconds

15

यदि आप बाद में गणना करने के लिए समय का उपयोग करने का इरादा रखते हैं, तो आउटपुट कोड के -fविकल्प का उपयोग करना सीखें जो समय बचाता है। यहाँ कुछ कोड है जिनका उपयोग मैंने हाल ही में छात्रों के कार्यक्रमों के संपूर्ण क्लास के निष्पादन समय को प्राप्त करने और क्रमबद्ध करने के लिए किया है:/usr/bin/time

fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...

मैंने बाद में सभी $timefileफाइलों को संक्षिप्त कर दिया और आउटपुट को लुआ दुभाषिया में बदल दिया । आप पायथन या बैश या अपने पसंदीदा सिंटैक्स के साथ भी ऐसा कर सकते हैं। मुझे इस तकनीक से प्यार है।


नोट: पूर्ण पथ /usr/bin/timeआवश्यक है क्योंकि यद्यपि which timeआप अन्यथा बताएंगे, यदि आप बस चलाते हैं time, तो यह आपके शेल के संस्करण को चलाएगा , timeजो किसी भी तर्क को स्वीकार नहीं करता है।
केविन पासे

मैं env time:-) के साथ जाऊंगा
Ciro Santilli 冠状

13

यदि आपको केवल दूसरे के लिए सटीकता की आवश्यकता है, तो आप बिल्ट $SECONDSचर का उपयोग कर सकते हैं , जो कि कुछ सेकंड की संख्या को गिनता है जो शेल चल रहा है।

while true; do
    start=$SECONDS
    some_long_running_command
    duration=$(( SECONDS - start ))
    echo "This run took $duration seconds"
    if some_condition; then break; fi
done

10

आप उपयोग कर सकते हैं timeऔर सबस्क्राइब कर सकते हैं ():

time (
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
)

या एक ही शेल में {}:

time {
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
}

आपने दो समान कोड स्निपेट पोस्ट किए हैं। आपके पास वहां कुछ अलग करने का मतलब होना चाहिए।
स्टैसन

3
@StasBekman सच नहीं है, पहले प्रयोग ( (और )नया संदर्भ, subshell ), और अन्य के साथ {और }(एक ही खोल, उसी संदर्भ)
एडुआर्डो कुओमो

अहा! मैं वास्तव में दोनों में बहुत मुश्किल लग रहा था और अंतर नहीं देखा। यह स्पष्ट करने के लिए धन्यवाद कि {} बनाम ()।
स्टैस्टन

2

रास्ता है

$ > g++ -lpthread perform.c -o per
$ > time ./per

आउटपुट >> है

real    0m0.014s
user    0m0.010s
sys     0m0.002s

उपयोग -lphtreadया -oटैग करने की आवश्यकता नहीं है । बस timeकमांड का उपयोग करने की आवश्यकता है , जिसे स्वीकृत उत्तर बेहतर बताते हैं।
डेनिस

7
यह एक उदाहरण था। यह मेरा प्रदर्शन है। थ्रेडिंग की आवश्यकता है, इसलिए मुझे -Lpread को और साधारण पहचान के लिए -o प्रति है।
रोबेल शर्मा

0

एक संभवतः सरल विधि (जो विभिन्न उपयोगकर्ताओं की आवश्यकताओं को पूरा नहीं कर सकती है) शेल का उपयोग है PROMPT.it एक सरल समाधान है जो कुछ मामलों में उपयोगी हो सकता है। आप नीचे दिए गए उदाहरण के रूप में बैश प्रॉम्प्टिंग सुविधा का उपयोग कर सकते हैं:

निर्यात PS1 = '[\ t \ u @ \ h] \ $' 

उपर्युक्त आदेश के परिणामस्वरूप शेल को बदल दिया जाएगा:

[HH: MM: SS यूजर @ होस्टनाम] $ 

हर बार जब आप एक कमांड चलाते हैं (या हिट दर्ज करते हैं) शेल प्रॉम्प्ट पर वापस लौटते हैं, तो प्रॉम्प्ट वर्तमान समय प्रदर्शित करेगा।

नोट्स:
1) सावधान रहें कि यदि आप अपना अगला कमांड टाइप करने से पहले कुछ समय तक इंतजार करते हैं, तो इस समय पर विचार करने की आवश्यकता है, अर्थात शेल प्रॉम्प्ट में प्रदर्शित समय टाइमस्टैम्प है जब शेल प्रॉम्प्ट प्रदर्शित किया गया था, न कि जब आप कमांड दर्ज करते हैं। कुछ उपयोगकर्ता अगली कमांड के लिए तैयार होने से पहले एक नए टाइमस्टैम्प के साथ एक नया संकेत प्राप्त करने के लिए Enter कुंजी को हिट करने का विकल्प चुनते हैं।
2) अन्य उपलब्ध विकल्प और संशोधक हैं जिनका उपयोग बैश प्रॉम्प्ट को बदलने के लिए किया जा सकता है, अधिक विवरण के लिए (मैन बैश) देखें।


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