ස්ක්‍රිප්ටයක් ක්‍රියාත්මක කිරීමේ කාලය effectively ලදායී ලෙස ලබා ගන්නේ කෙසේද?


398

තිර රචනයක සම්පූර්ණ කාලය ප්‍රදර්ශනය කිරීමට මම කැමතියි.

මම දැනට කරන්නේ -

#!/bin/bash
date  ## echo the date at start
# the script contents
date  ## echo the date at end

මෙය පෙන්වන්නේ තිර රචනය ආරම්භ වන හා අවසන් වන කාලයයි. ප්‍රොසෙසර් වේලාව / io වේලාව වැනි සියුම් නිමැවුම් ප්‍රදර්ශනයක් පෙන්විය හැකිද?



තාවකාලික උච්චාවචනයන් නිසා දැනට පිළිගත් පිළිතුර ඇත්ත වශයෙන්ම ප්‍රමාණවත් නොවන බව මම සිතමි.
Léo Léopold Hertz 준영

1
@CiroSantilli 烏坎 事件 2016 六四 tempo temp තාවකාලික සිදුවීම්වල බලපෑම තුරන් කිරීම සඳහා ඔබේ යෝජිත නූල් තවමත් ප්‍රමාණවත් නොවන බව මම සිතමි.
Léo Léopold Hertz 준영

එසේම සම්බන්ධ: stackoverflow.com/questions/5152858/… හෝ තරමක් unix.stackexchange.com/questions/334145/…
phk

ඔබට ක්‍රියාත්මක කළ හැකි විධානයක් ඇති අතර එය සියලු යුනික්ස් විධාන ස්වයංක්‍රීයව වාර ගණනක් කරයි, සක්‍රීය කරන්නේ කෙසේදැයි අමතක වී තිබේද?
කුඩු 366

Answers:


512

timeඔබ ස්ක්‍රිප්ට් එක අමතන විට භාවිතා කරන්න:

time yourscript.sh

76
මෙම තුන් වරක් ප්රතිදානයනට: real, userසහ sys. මේවායේ අර්ථයන් සඳහා, මෙහි බලන්න .
ගැරට්

33
සහ "තාත්වික" යනු බොහෝ විට මිනිසුන්ට දැන ගැනීමට අවශ්‍ය දෙයයි - "රියල් යනු බිත්ති ඔරලෝසු කාලය - ඇමතුම ආරම්භයේ සිට අවසානය දක්වා කාලය"
බ්‍රැඩ් පාර්ක්ස්

4
Stdout ගොනුවකට ග්‍රහණය කර ගැනීමට ක්‍රමයක් තිබේද? උදාහරණයක් ලෙස, වැනි දෙයක්time $( ... ) >> out.txt
ජෝන්

2
විධාන රේඛාවේ විධාන අනුපිළිවෙලටද ඔබට මෙය කළ හැකිය, උදා:time (command1 && command2)
metar

2
නැතහොත් ඔහුගේ පිටපතෙහි ඔහුට කළ හැක්කේ මෙයයි: ප්‍රතිරාවය $ තත්පර එය බාෂ් යැයි උපකල්පනය කරයි ....
ස්කොට් ප්‍රයිව්

209

නම් timeවිකල්පයක් නොවේ,

start=`date +%s`
stuff
end=`date +%s`

runtime=$((end-start))

33
මෙය ක්‍රියාත්මක වන්නේ ඔබට උප තත්පර නිරවද්‍යතාවයක් අවශ්‍ය නොවන්නේ නම් පමණක් බව සලකන්න. පිළිගත හැකි සමහර භාවිතයන් සඳහා, අනෙක් ඒවා සඳහා නොවේ. තරමක් නිරවද්යතාව සඳහා (ඔබ තවමත් කැඳවමින් කරන්නේ dateදෙවරක්, උදාහරණයක් ලෙස, ඔබ විය හැකි නිසා හොඳම අඩු බොහෝ විට ප්රායෝගිකව මිලි තත්පර නිරවද්යතාවයකින් ලබා ගැනීම, සහ), භාවිතා කිරීමට උත්සාහ කරන්න date +%s.%N. ( %Nමුළු තත්පරයෙන් නැනෝ තත්පර වේ.)
සීවීඑන්

1
මෙය කදිමයි, නමුත් @ මයිකල්ජෝර්ලිංගේ දියුණුවත් සමඟ මට පහත දෝෂය ඇතිවේ: bash: 1390472071.282341976: syntax error: invalid arithmetic operator (error token is ".282341976")එබැවින් සමහර විට මෙය වඩාත් පැහැදිලි කිරීමක් අවශ්‍ය වේ.
ක්‍රිස් එච්

4
H ක්‍රිෂ් ඔහ්. එය පෙන්වා දීම හොඳ ය; bash අංක ගණිත ප්‍රසාරණය පූර්ණ සංඛ්‍යාවක් පමණි. මම පැහැදිලි විකල්ප දෙකක් දකිමි; එක්කෝ කාල ආකෘති පත්‍රයේ කාල පරාසය ඉවත් කරන්න (සහ එහි ප්‍රති result ල යුගය යුගයේ සිට නැනෝ තත්පර ලෙස සලකන්න), එබැවින් jwchew යෝජනා කරන අගයන් දෙකෙන් සත්‍ය ධාවන කාලය ගණනය කිරීමට date +%s%Nවඩා වැඩි යමක් භාවිතා කරන්න, නැතහොත් භාවිතා කරන්න bc. කෙසේ වෙතත්, මෙම ප්‍රවේශය එය කළ හැකි උපක්‍රමයක් බව මට හැඟේ; timeඉහත දක්වා ඇති හේතු නිසා ලබා ගත හැකි නම් වඩා හොඳය.
සීවීඑන්

10
ස්ථාපනය bcකර මෙය කරන්න:runtime=$( echo "$end - $start" | bc -l )
redolent

11
ඔබේ ස්ක්‍රිප්ටයට මිනිත්තු කිහිපයක් ගත වේ නම්, භාවිතා කරන්න:echo "Duration: $((($(date +%s)-$start)/60)) minutes
rubo77

77

timesඔබගේ ස්ක්‍රිප්ට් එකෙන් පිටවීම ගැන තර්කයකින් තොරව අමතන්න .

සමඟ kshහෝ zsh, ඔබට timeඒ වෙනුවට භාවිතා කළ හැකිය . සමඟ zsh, පරිශීලකයාට සහ පද්ධතියේ CPU වේලාවට timeඅමතරව බිත්ති ඔරලෝසු කාලයද ලබා දෙනු ඇත .

ඔබගේ ස්ක්‍රිප්ටයේ පිටවීමේ තත්වය ආරක්ෂා කර ගැනීම සඳහා, ඔබට එය කළ හැකිය:

ret=$?; times; exit "$ret"

නැතහොත් ඔබට උගුලක් එකතු කළ හැකිය EXIT:

trap times EXIT

ඒ ආකාරයෙන්, කවචය පිටවන සෑම විටම වේලාවන් කැඳවනු ලබන අතර පිටවීමේ තත්වය ආරක්ෂා වේ.

$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
shell  0.67s user 0.01s system 100% cpu 0.677 total
children  0.00s user 0.00s system 0% cpu 0.677 total

ද සියලු බවයි සටහන් bash, kshහා zshඇති $SECONDSසෑම දෙවන ස්වයංක්රීයව නිලධාරිෙයකු රැඳි විශේෂ විචල්ය. දෙකෙහිම zshසහ ksh93, එම විචල්‍යය typeset -F SECONDSවඩාත් නිරවද්‍යතාව ලබා ගැනීම සඳහා පාවෙන ලක්ෂ්‍යයක් (සමඟ ) කළ හැකිය. මෙය බිත්ති ඔරලෝසු කාලය මිස CPU වේලාව නොවේ.


12
එම $ SECONDS විචල්‍යය ඉතා ප්‍රයෝජනවත් වේ, ස්තූතියි!
andybuckley

1
ඔබගේ ප්‍රවේශය තාවකාලික සිදුවීම්වල බලපෑම ඉවත් කරයිද? - - මම හිතන්නේ ඔබේ ප්‍රවේශය timeකලින් ඉදිරිපත් කළ ප්‍රවේශය ආසන්නයේ . - - timeitMATLAB කේතයේ ඉදිරිපත් කර ඇති ප්‍රවේශය මෙහි ප්‍රයෝජනවත් වනු ඇතැයි මම සිතමි .
Léo Léopold Hertz 준영

2
හායි, @ ස්ටෙෆාන් චසෙලාස්. මට තේරුණා timesබිත්ති කාලය දෙන්නෙ නෑ නේද? උදාහරණයක් ලෙස,bash -c 'trap times EXIT;sleep 2'
user15964


32

මම බෑන්ඩ්වැගන් වෙත ටිකක් ප්‍රමාදයි, නමුත් සෙවීම තුළින් අනෙක් අය මෙම නූලට පැකිලීමට සිදුවුවහොත් මගේ විසඳුම (උප තත්පර නිරවද්‍යතාව සඳහා) පළ කිරීමට අවශ්‍ය විය. ප්‍රතිදානය දින, පැය, මිනිත්තු සහ අවසාන තත්පර ආකාරයෙන් වේ:

res1=$(date +%s.%N)

# do stuff in here

res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)

LC_NUMERIC=C printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds

පිටත සිටින කෙනෙකුට මෙය ප්‍රයෝජනවත් වේ යැයි සිතමි!


1
ගණනය කිරීම් සඳහා 'බීසී' භාවිතා කිරීම හැර වෙනත් (බාෂ් පමණක්) ක්‍රමයක් නොමැති බව මම අනුමාන කරමි. BTW ඇත්තෙන්ම හොඳ පිටපත;)
tvl

1
FreeBSD හි dateඋප තත්පර නිරවද්‍යතාවයට සහය නොදක්වන අතර කාලරාමුව සඳහා වචනාර්ථයෙන් “ N” එකතු කරනු ඇත .
ඇන්ටන් සැම්සොනොව්

1
ඉතා හොඳ පිටපතක්, නමුත් මගේ බෑෂ් උප තත්පර කොටස හසුරුවන්නේ නැත. මමත් ඉගෙන ගත්තා, bc හි / 1 effectively ලදායී ලෙස එය ඉවත් කරයි, එබැවින් මම s ds ගණනය කිරීමට @ / 1 added එකතු කළෙමි, එය දැන් ඉතා හොඳ දේවල් පෙන්වයි!
ඩැනියෙල්

1
bc මොඩියුලෝ සඳහා සහය දක්වයි : dt2=$(echo "$dt%86400" | bc). කියමින් ... BTW මම පෝරමයට කැමතියි dt2=$(bc <<< "${dt}%86400")නමුත් එය සම්පූර්ණයෙන්ම පුද්ගලිකයි.
ඩැනී_එල්

23

මගේ ක්‍රමය bash:

# Reset BASH time counter
SECONDS=0
    # 
    # do stuff
    # 
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"

1
මෙය ගත වූ කාලය පෙන්වයි, නමුත් එය ප්‍රශ්නයේ දී ඉල්ලා ඇති පරිදි “ප්‍රොසෙසර් වේලාව, අයි / ඕ වේලාව වැනි සියුම් ප්‍රතිදානය පෙන්වන්නේ නැත.
රෝයිමා

4
මතු වී ඇති ප්‍රශ්නයට පිළිතුරක් සොයන අයට මෙම විසඳුම ප්‍රයෝජනවත් වනු ඇත. ඔබගේ අදහස OPs ප්‍රශ්නයට වඩා හොඳින් විසඳනු ඇත.
මාක්

8

මෙම ප්‍රශ්නය තරමක් පැරණි නමුත් එය කිරීමට මගේ ප්‍රියතම ක්‍රමය සොයා ගැනීමට උත්සාහ කිරීමේදී මෙම ත්‍රෙඩ් එක ඉහළට පැමිණියේය ... කිසිවෙකු එය සඳහන් නොකිරීම ගැන මම පුදුම වෙමි:

perf stat -r 10 -B sleep 1

'පර්ෆ්' යනු කර්නල් තුළ 'මෙවලම් / පර්ෆ්' යටතේ ඇතුළත් කර ඇති කාර්ය සාධන විශ්ලේෂණ මෙවලමක් වන අතර එය බොහෝ විට වෙනම පැකේජයක් ලෙස ස්ථාපනය කිරීමට ලබා ගත හැකිය (සෙන්ටෝස් හි 'පර්ෆ්' සහ ඩෙබියන් / උබුන්ටු මත 'ලිනක්ස්-මෙවලම්'). ලිනක්ස් කර්නල් පර්ෆ් විකියෙහි ඒ පිළිබඳ තවත් බොහෝ තොරතුරු ඇත.

'පර්ෆ් ස්ටාට්' ධාවනය කිරීමෙන් අවසානයේ ක්‍රියාත්මක වන සාමාන්‍ය කාලය ඇතුළුව විස්තර ටිකක් ලැබේ:

1.002248382 seconds time elapsed                   ( +-  0.01% )

2
කුමක්ද perf?
බී ලේයර්

L බී ලේයර් - 'පර්ෆ්' පිළිබඳ කෙටි විස්තරයක් ලබා දීම සඳහා මගේ පිළිතුර සංස්කරණය කළේය.
සහීඩ්

1
perf statදැන් පැමිණිලි කරන්නේ "සංඛ්‍යාලේඛන එකතු කිරීමට ඔබට අවසර නොමැති විය හැකිය." ඔබ සමහර විධානයන් සමඟ ධාවනය නොකරන්නේ නම් sudo, එමඟින් ඔබට ඉලක්කගත යන්ත්‍රයක් සම්පූර්ණයෙන්ම හිමි නොවන සෑම අවස්ථාවකම එය නිෂ් less ල වේ.
ඇලමාර්

පුදුමයි, ස්තූතියි! timeඅනෙක් අය යෝජනා කරනවාට වඩා සියුම් විසඳුමක් ලබා දෙන්න . විශේෂයෙන්, timeකේත තරඟ විසඳුම් මැනීමට අදාළ නොවේ (එය කාලය මිලි තත්පර හා අඩු මුද්‍රණය නොකරන බැවින්) , නමුත් ඔබේ විසඳුම එසේ නොවේ.
හායි-ඒන්ජල්

6
#!/bin/bash
start=$(date +%s.%N)

# HERE BE CODE

end=$(date +%s.%N)    
runtime=$(python -c "print(${end} - ${start})")

echo "Runtime was $runtime"

ඔව්, මෙය පයිතන් ලෙස හැඳින්වේ, නමුත් ඔබට එය සමඟ ජීවත් විය හැකි නම් මෙය ඉතා හොඳ, දැඩි විසඳුමකි.


5
එම pythonවිධානය උප කුලකයකින් ධාවනය කර එහි ප්‍රතිදානය කියවීම බොහෝ වර්තමාන පද්ධතිවල නැනෝ තත්පර මිලියන ගණනක් ගතවනු ඇතැයි පරිස්සම් වන්න . ධාවනය සඳහා සමාන වේ date.
ස්ටෙෆාන් චසෙලාස්

8
“නැනෝ තත්පර මිලියන කිහිපයක්” යනු මිලි තත්පර කිහිපයකි. මිනිසුන් ටයිම් කරන බාෂ් ස්ක්‍රිප්ට් සාමාන්‍යයෙන් ඒ ගැන එතරම් තැකීමක් නොකරයි (ඔවුන් මෙගා තත්පරයකට පිටපත් බිලියන ගණනක් ධාවනය නොකරන්නේ නම්).
සිල්ක්

4
පයිතන් ක්‍රියාවලියක් තුළ ගණනය කිරීම සිදු කළද, පයිතන් ආයාචනා කිරීමට පෙර අගයන් මුළුමනින්ම එකතු කරන ලද බව සලකන්න. පිටපත ක්‍රියාත්මක කිරීමේ වේලාව “නැනෝ තත්පර මිලියන” ඉහළින් තොරව නිවැරදිව මනිනු ලැබේ.
වික්ටර් ෂ්‍රෝඩර්

5

පුද්ගලිකව, මම කැමතියි මගේ සියලුම ස්ක්‍රිප්ට් කේතය සමහර “ප්‍රධාන” ශ්‍රිතයක් තුළට එතීමට:

main () {
 echo running ...
}

# stuff ...

# calling the function at the very end of the script
time main

timeමෙම අවස්ථාවෙහිදී විධානය භාවිතා කිරීම කොතරම් පහසුදැයි බලන්න . නිසැකවම ඔබ ස්ක්‍රිප්ට් විග්‍රහ කිරීමේ වේලාව ඇතුළුව නිශ්චිත වේලාව මනින්නේ නැත, නමුත් බොහෝ අවස්ථාවන්හිදී එය ප්‍රමාණවත් තරම් නිවැරදි බව මට පෙනේ.


5

ඔවුන්ගේ කාලය මැනීම සඳහා විධාන වලට පෙර එකතු කළ හැකි කුඩා ෂෙල් ශ්‍රිතයක්:

tm() {
  local start=$(date +%s)
  $@
  local exit_code=$?
  echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}"
  return $exit_code
}

ඉන්පසු එය ඔබගේ ස්ක්‍රිප්ටයේ හෝ ඔබේ විධාන රේඛාවේ භාවිතා කරන්න:

tm the_original_command with all its parameters

මිලි තත්පර එකතු කිරීම වටී, උත්සාහ කළ ඉල්කේ s=$(date +%s000), එය ක්‍රියාත්මක වේදැයි විශ්වාස නැත.
loretoparisi

2
මිලි තත්පර සඳහා @loretoparisi, ඔබට උත්සාහ කළ හැකිය date +%s%N. Serverfault.com/questions/151109/…
jpbochi

3

මෙන්න ඇලෙක්ස්ගේ පිළිතුරේ විචලනයකි. මම සැලකිලිමත් වන්නේ මිනිත්තු සහ තත්පර ගැන පමණයි, නමුත් මට අවශ්‍ය වූයේ එය වෙනස් ආකාරයකින් සංයුති කිරීමයි. ඉතින් මම මේක කළා:

start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")

1
පහත වැටීම ඇයි? මට දෝෂයක් තිබේද?
mpontillo

3
#!/bin/csh
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -V
#PBS -M shihcheng.guo@gmail.com
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
do
echo 1
done
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."

7
dateස්ක්‍රිප්ටයට පෙර සහ පසු භාවිතා කරන සහ ඒවා අතර වෙනස ප්‍රතිදානය කරන දැනටමත් ලබා දී ඇති අනෙක් පිළිතුරු වලට වඩා මෙය සැබවින්ම වෙනස් වන්නේ කෙසේද?
එරික් රෙනූෆ්

3

බාෂ් පමණක් භාවිතා කිරීමෙන් ෂෙල් ස්ක්‍රිප්ටයේ කොටසක් සඳහා කාල සීමාව මැනීමට සහ ගණනය කිරීමට හැකිය (හෝ සමස්ත පිටපත සඳහා ගත වූ කාලය):

start=$SECONDS

... # do time consuming stuff

end=$SECONDS

ඔබට දැන් වෙනස මුද්‍රණය කළ හැකිය:

echo "duration: $((end-start)) seconds."

ඔබට අවශ්‍ය වන්නේ වර්ධක කාල සීමාව පමණි:

echo "duration: $((SECONDS-start)) seconds elapsed.."

ඔබට කාල සීමාව විචල්යයකින් ගබඩා කළ හැකිය:

let diff=end-start

1
^ මෙය පිළිතුරකි. හෝ වඩාත් සරලව: ON අවසානයේ තත්පර. එය BUILT-IN Bash විචල්‍යයකි. අනෙක් සියලුම පිළිතුරු මෙම රෝදය නැවත ප්‍රතිනිර්මාණය කිරීම සඳහා අමතර වැඩක් කරමින් සිටී ...
ස්කොට් ප්‍රයිව්

2

SECONDSදෙවන මට්ටමේ කැටිති වලට පමණක් සීමා වූ කාල ශ්‍රිතය බාහිර විධානයන් භාවිතා නොකරයි:

time_it() {
  local start=$SECONDS ts ec
  printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
  printf '%s\n' "$ts Starting $*"
  "$@"; ec=$?
  printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
  printf '%s\n' "$ts Finished $*; elapsed = $((SECONDS-start)) seconds"
  # make sure to return the exit code of the command so that the caller can use it
  return "$ec"
}

උදාහරණයක් වශයෙන්:

time_it sleep 5

ලබා දෙයි

2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished
sleep 5; elapsed = 5 seconds

1
#!/bin/bash
begin=$(date +"%s")

Script

termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."

0

Bash සඳහා, අභ්‍යන්තර $SECONDSවිචල්‍යය භාවිතා කරන්න . මෙන්න නිරූපණයක්:

(තත්පර 1 = මිනිත්තු ගණනක්) සිට මේ අවස්ථාවේ දී dt_minවටකුරු වන බව සලකන්න . මෙම ඔබ ලකුණු හා වේලාව ඔබේ තිර රචනය කතා කියලා එහිදී පහත කොටසක්, නමුත් මම මේ Demo වෙනුවෙන් වෙනුවට දෙවන 1 නිදාගෙන ඉන්නේ:0.01666666666...0.017printfsleep 1;

start=$SECONDS; sleep 1; end=$SECONDS; dt_sec=$(( end - start )); dt_min=$(printf %.3f $(echo "$dt_sec/60" | bc -l)); echo "dt_sec = $dt_sec; dt_min = $dt_min"
dt_sec = 1; dt_min = 0.017

ආශ්‍රිත:


0

බාෂ් ටයිම් බිල්ඩින් භාවිතා කරන්නද?

time: time [-p] PIPELINE
    Execute PIPELINE and print a summary of the real time, user CPU time,
    and system CPU time spent executing PIPELINE when it terminates.
    The return status is the return status of PIPELINE.  The `-p' option
    prints the timing summary in a slightly different format.  This uses
    the value of the TIMEFORMAT variable as the output format.

උදාහරණයක්:

TIMEFORMAT="The command took %Rs"
time {
    sleep 0.1
}

ප්‍රතිදානය:

The command took 0.108s
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.