Dapatkan waktu eksekusi program di shell


407

Saya ingin mengeksekusi sesuatu di shell linux dalam beberapa kondisi yang berbeda, dan dapat menampilkan waktu eksekusi dari setiap eksekusi.

Saya tahu saya bisa menulis skrip perl atau python yang akan melakukan ini, tetapi apakah ada cara saya bisa melakukannya di shell? (yang kebetulan bash)


2
Kasing

apakah mungkin untuk mendapatkan Tickscase seperti windows?
freeforall tousez

Jawaban:


534

Gunakan timekata kunci bawaan:

$ waktu bantuan

waktu: waktu [-p] PIPELINE
    Jalankan PIPELINE dan cetak ringkasan waktu nyata, waktu CPU pengguna,
    dan waktu CPU sistem yang digunakan untuk mengeksekusi PIPELINE saat itu berakhir.
    Status pengembalian adalah status pengembalian dari PIPELINE. Opsi `-p '
    mencetak ringkasan waktu dalam format yang sedikit berbeda. Ini menggunakan
    nilai variabel TIMEFORMAT sebagai format output.

Contoh:

$ time sleep 2
0m2.009s nyata
pengguna 0m0,000s
sys 0m0.004s

1
Bagaimana ini digunakan pada perintah seperti time -p i=x; while read line; do x=x; done < /path/to/file.txt? Segera mengembalikan 0,00 kecuali saya tidak meletakkan sesuatu sebelum loop sementara .. apa yang terjadi?
natli

ini adalah versi 'waktu' yang buruk, bash builtin. di mana perintah 'waktu' eksternal?
Znik

6
@Znik, coba / usr / bin / waktu
Mark Rajcok

10
@natli: Meskipun timedapat mengatur waktu seluruh pipa apa adanya (berdasarkan menjadi kata kunci Bash ), Anda perlu menggunakan perintah grup ({ ...; ...; } ) untuk time -p { i=x; while read line; do x=x; done < /path/to/file.txt; }
menentukan

2
Untuk melihat semua versi waktu yang telah Anda instal pada sistem Anda, Anda dapat menggunakan type -a time
spinup

120

Anda bisa mendapatkan informasi yang lebih detail daripada bash built-in time(yang Robert Gamble sebutkan) menggunakan waktu (1) . Biasanya ini /usr/bin/time.

Catatan editor: Untuk memastikan bahwa Anda menggunakan utilitas eksternal time daripada milik shell Andatime kata kunci , panggil sebagai /usr/bin/time.
timeadalah utilitas yang diamanatkan POSIX , tetapi satu-satunya opsi yang diperlukan untuk mendukungnya adalah -p.
Platform tertentu menerapkan tertentu, ekstensi tidak standar: -vbekerja dengan GNU 'stime utilitas, seperti yang ditunjukkan di bawah ini (pertanyaannya adalah ditandai); implementasi BSD / macOS digunakan -luntuk menghasilkan keluaran yang serupa - lihat man 1 time.

Contoh keluaran verbose:


$ /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
Anda tidak akan tahu paket debian apa yang akan datang? tampaknya tidak diinstal secara default
ʞɔıu

1
Saya merujuk posting Anda Robert. Kecuali Anda maksud perintah yang Anda sarankan bukan bash built-in?
grepsedawk

24
Hebatnya, itu diinstal dari paket yang disebut "waktu".
Paul Tomblin

2
Output dari / usr / bin / time terlihat seperti "0,00 pengguna 0,00 sistem 0: 02.00 CPU 0% (0avgtext + 0avgdata 0maxresident) k 0inputs + 0outputs (0major + 172minor) pagefault 0swaps"
Paul Tomblin

4
@Nick: "sudo apt-get install time".
Robert Gamble

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
Ada banyak cara yang lebih sederhana. Bash menghitung secara otomatis variabel khusus $ DETIK, kemudian perhitungan ulang berdasarkan perintah tanggal eksternal tidak diperlukan. Variabel $ SECONDS menyimpan berapa detik skrip bash berjalan saat dijalankan. Variabel ini memiliki beberapa properti khusus. Lihat halaman manual: D
Znik

Saya sudah mencoba keduanya di atas & metode dalam komentar. Pada tanggal 1 saya mendapatkan kesalahan 'variabel ilegal' & ke-2 saya mendapatkan 'variabel tidak dikenal'
DrBwts

45

Untuk pengukuran delta baris demi baris, coba gnomon .

Utilitas baris perintah, sedikit seperti ts moreutils, untuk menambahkan informasi stempel waktu ke output standar dari perintah lain. Berguna untuk proses jangka panjang di mana Anda ingin catatan sejarah tentang apa yang butuh waktu lama.

Anda juga dapat menggunakan opsi --highdan / atau --mediumuntuk menentukan ambang panjang dalam detik, di mana gnomon akan menyorot timestamp berwarna merah atau kuning. Dan Anda dapat melakukan beberapa hal lain juga.

contoh


3
Tip yang bagus, tetapi hanya untuk memperjelas: ini berguna untuk penentuan waktu baris per baris , tetapi biaya tambahan dari pengambilan waktu yang berbutir halus seperti itu secara signifikan menambah waktu keseluruhan .
mklement0

2
Utilitas yang luar biasa .. Terima kasih telah berbagi
Kishan B

19

Jika Anda ingin lebih presisi, gunakan %Ndengan date(dan gunakan bcuntuk diff, karena $(())hanya menangani bilangan bulat).

Inilah cara melakukannya:

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

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

Contoh:

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

Hasil:

Execution time: 0.104623 seconds

15

Jika Anda berniat menggunakan waktu untuk menghitung, pelajari cara menggunakan -fopsi /usr/bin/timeuntuk menghasilkan kode yang menghemat waktu. Berikut adalah beberapa kode yang saya gunakan baru-baru ini untuk mendapatkan dan mengurutkan waktu pelaksanaan dari seluruh kelas program siswa:

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...

Saya kemudian menggabungkan semua $timefilefile dan menyalurkan output ke juru bahasa Lua . Anda dapat melakukan hal yang sama dengan Python atau bash atau apa pun sintaks favorit Anda. Saya suka teknik ini.


Catatan: Path lengkap /usr/bin/timediperlukan karena meskipun which timeakan memberi tahu Anda sebaliknya, jika Anda hanya menjalankan time, itu akan menjalankan versi shell Anda timeyang tidak menerima argumen apa pun.
Kevin Dice


13

Jika Anda hanya membutuhkan ketelitian untuk yang kedua, Anda dapat menggunakan $SECONDSvariabel bawaan , yang menghitung jumlah detik bahwa shell telah berjalan.

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

Anda dapat menggunakan timedan subkulit () :

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

Atau dalam shell yang sama {}:

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

Anda memposting dua cuplikan kode yang identik. Anda pasti bermaksud memiliki sesuatu yang berbeda di sana.
stason

3
@StasBekman tidak benar, pertama menggunakan (& )(konteks baru, subkulit ), dan lainnya dengan {& }(shell yang sama, konteks yang sama)
Eduardo Cuomo

Aha! Saya melihat sangat keras pada keduanya dan tidak melihat perbedaannya. Terima kasih telah menjelaskannya {} vs ().
stason

2

Jalannya adalah

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

output adalah >>

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

Tidak perlu menggunakan -lphtreadatau -otag. Hanya perlu menggunakan timeperintah, yang jawaban yang diterima menjelaskan lebih baik.
Dennis

7
Itu adalah contoh. Itu adalah perform.c saya memiliki threading jadi saya perlu -lpthread dan untuk identitas sederhana itu -o per.
Robel Sharma

0

satu metode yang mungkin sederhana (yang mungkin tidak memenuhi kebutuhan pengguna yang berbeda) adalah penggunaan shell PROMPT.it adalah solusi sederhana yang dapat berguna dalam beberapa kasus. Anda dapat menggunakan fitur bash prompt seperti pada contoh di bawah ini:

export PS1 = '[\ t \ u @ \ h] \ $' 

Perintah di atas akan menghasilkan perubahan prompt shell ke:

[HH: MM: SS username @ hostname] $ 

Setiap kali Anda menjalankan perintah (atau tekan enter) kembali ke prompt shell, prompt akan menampilkan waktu saat ini.

Catatan:
1) berhati-hatilah bahwa jika Anda menunggu beberapa saat sebelum Anda mengetik perintah berikutnya, maka kali ini perlu dipertimbangkan, yaitu waktu yang ditampilkan dalam prompt shell adalah timestamp ketika prompt shell ditampilkan, bukan ketika Anda memasukkan perintah. beberapa pengguna memilih untuk menekan tombol Enter untuk mendapatkan prompt baru dengan stempel waktu baru sebelum mereka siap untuk perintah berikutnya.
2) Ada opsi dan pengubah lain yang tersedia yang dapat digunakan untuk mengubah prompt bash, lihat (man bash) untuk detail lebih lanjut.


Bukan itu intinya ketika program dieksekusi, tetapi durasi eksekusi program.
Geno Chen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.