Πώς να χρησιμοποιήσετε την εντολή χρόνου στο Linux

Θέλετε να μάθετε πόσο διαρκεί μια διαδικασία και πολλά άλλα; Η εντολή Linux time επιστρέφει στατιστικά χρόνου, παρέχοντάς σας καταπληκτικές πληροφορίες σχετικά με τους πόρους που χρησιμοποιούνται από τα προγράμματά σας.

Ο χρόνος έχει πολλούς συγγενείς

Υπάρχουν πολλές διανομές Linux και διαφορετικά λειτουργικά συστήματα που μοιάζουν με Unix. Κάθε ένα από αυτά έχει ένα προεπιλεγμένο κέλυφος εντολών. Το πιο κοινό προεπιλεγμένο κέλυφος στις σύγχρονες διανομές Linux είναι το bash shell. Υπάρχουν όμως πολλά άλλα, όπως το κέλυφος Z (zsh) και το κέλυφος Korn (ksh).

Όλα αυτά τα κελύφη ενσωματώνουν τη δική τους εντολή χρόνου, είτε ως α ενσωματωμένο εντολή ή ως α δεσμευμένη λέξη. Όταν πληκτρολογείτε time σε ένα παράθυρο τερματικού, το κέλυφος θα εκτελέσει την εσωτερική του εντολή αντί να χρησιμοποιεί το δυαδικό αρχείο χρόνου GNU που παρέχεται ως μέρος της διανομής σας Linux.

Θέλουμε να χρησιμοποιήσουμε την έκδοση του χρόνου GNU γιατί έχει περισσότερο επιλογές και είναι πιο ευέλικτο.

Ποια ώρα θα τρέξει;

Μπορείτε να ελέγξετε ποια έκδοση θα εκτελεστεί χρησιμοποιώντας την εντολή type. Ο τύπος θα σας ενημερώσει εάν το κέλυφος θα χειριστεί την εντολή σας, με τις εσωτερικές του ρουτίνες ή θα τη μεταβιβάσει στο δυαδικό GNU.

σε ένα παράθυρο τερματικού πληκτρολογήστε τον τύπο λέξης, ένα διάστημα και, στη συνέχεια, τη λέξη ώρα και πατήστε Enter.

type time

Μπορούμε να δούμε ότι στο bash shell ο χρόνος είναι μια δεσμευμένη λέξη. Αυτό σημαίνει ότι το Bash θα χρησιμοποιεί τις ρουτίνες εσωτερικού χρόνου του από προεπιλογή.

type time

Στο κέλυφος Z (zsh) ο χρόνος είναι μια δεσμευμένη λέξη, επομένως οι ρουτίνες του εσωτερικού φλοιού θα χρησιμοποιούνται από προεπιλογή.

type time

Στο κέλυφος Korn ο χρόνος είναι μια λέξη-κλειδί. Θα χρησιμοποιηθεί μια εσωτερική ρουτίνα αντί της εντολής χρόνου GNU.

Εκτέλεση της εντολής χρόνου GNU

Εάν το κέλυφος στο σύστημα Linux σας έχει μια εσωτερική ρουτίνα ώρας, θα πρέπει να είστε ξεκάθαροι εάν θέλετε να χρησιμοποιήσετε το δυαδικό χρονοδιάγραμμα GNU. Πρέπει είτε:

Παρέχετε ολόκληρη τη διαδρομή προς το δυαδικό αρχείο, όπως /usr/bin/time. Εκτελέστε την εντολή who time για να βρείτε αυτό το μονοπάτι.
Χρησιμοποιήστε χρόνο εντολής.
Χρησιμοποιήστε ανάστροφη κάθετο όπως ο χρόνος.

  Πώς να παίξετε Spelunky στο Linux

Η εντολή who time μας δίνει τη διαδρομή προς το δυαδικό.

Μπορούμε να το δοκιμάσουμε χρησιμοποιώντας το /usr/bin/time ως εντολή για την εκκίνηση του δυαδικού GNU. Που λειτουργεί. Λαμβάνουμε μια απάντηση από την εντολή time που μας λέει ότι δεν παρέχουμε παραμέτρους της γραμμής εντολών για να λειτουργήσει.

Η πληκτρολόγηση χρόνου εντολής λειτουργεί επίσης και λαμβάνουμε τις ίδιες πληροφορίες χρήσης από το χρόνο. Η εντολή εντολής λέει στο κέλυφος να αγνοήσει την επόμενη εντολή, ώστε να υποβληθεί σε επεξεργασία εκτός του κελύφους.

Η χρήση ενός χαρακτήρα πριν από το όνομα της εντολής είναι ίδια με τη χρήση της εντολής πριν από το όνομα της εντολής.

Ο απλούστερος τρόπος για να διασφαλίσετε ότι χρησιμοποιείτε το δυαδικό χρονοδιάγραμμα GNU είναι να χρησιμοποιήσετε την επιλογή ανάστροφης κάθετο.

time
time

Ο χρόνος επικαλείται την έκδοση του φλοιού του χρόνου. ο χρόνος χρησιμοποιεί το δυαδικό χρόνο.

Χρήση της εντολής ώρας

Ας χρονομετρήσουμε μερικά προγράμματα. Χρησιμοποιούμε δύο προγράμματα που ονομάζονται loop1 και loop2. Δημιουργήθηκαν από τα loop1.c και loop2.c. Δεν κάνουν τίποτα χρήσιμο εκτός από την επίδειξη των επιπτώσεων ενός τύπου αναποτελεσματικότητας κωδικοποίησης.

Αυτό είναι το loop1.c. Το μήκος μιας συμβολοσειράς απαιτείται εντός των δύο ένθετων βρόχων. Το μήκος λαμβάνεται εκ των προτέρων, έξω από τους δύο ένθετους βρόχους.

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main (int argc, char* argv[])
{
 int i, j, len, count=0;
 char szString[]="how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek";

 // get length of string once, outside of loops
 len = strlen( szString );  

 for (j=0; j

This is loop2.c. The length of the string is obtained time after time for every cycle of the outer loop. This inefficiency ought to show up in the timings.

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int main (int argc, char* argv[])
{
 int i, j, count=0;
 char szString[]="how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek-how-to-geek";

 for (j=0; j

Let’s fire up the loop1 program and use time to measure its performance.

time ./loop1

Τώρα ας κάνουμε το ίδιο για το loop2.

time ./loop2

Αυτό μας έδωσε δύο σειρές αποτελεσμάτων, αλλά είναι σε μια πραγματικά άσχημη μορφή. Μπορούμε να κάνουμε κάτι για αυτό αργότερα, αλλά ας διαλέξουμε μερικές πληροφορίες από τα αποτελέσματα.

Όταν εκτελούνται τα προγράμματα, υπάρχουν δύο τρόποι εκτέλεσης μεταξύ των οποίων εναλλάσσονται εμπρός και πίσω. Αυτά ονομάζονται λειτουργία χρήστη και λειτουργία πυρήνα.

Εν συντομία, μια διεργασία σε λειτουργία χρήστη δεν μπορεί να έχει απευθείας πρόσβαση στο υλικό ή στη μνήμη αναφοράς εκτός της δικής της εκχώρησης. Για να αποκτήσετε πρόσβαση σε τέτοιους πόρους, η διαδικασία πρέπει να υποβάλει αιτήματα στον πυρήνα. Εάν ο πυρήνας εγκρίνει το αίτημα, η διαδικασία εισέρχεται σε εκτέλεση λειτουργίας πυρήνα μέχρι να ικανοποιηθεί η απαίτηση. Στη συνέχεια, η διαδικασία επιστρέφει στην εκτέλεση λειτουργίας χρήστη.

Τα αποτελέσματα για το loop1 μας λένε ότι ο loop1 πέρασε 0,09 δευτερόλεπτα σε λειτουργία χρήστη. Είτε ξόδεψε μηδενικό χρόνο σε λειτουργία πυρήνα είτε ο χρόνος σε λειτουργία πυρήνα είναι πολύ χαμηλή τιμή για να καταχωρηθεί αφού στρογγυλοποιηθεί προς τα κάτω. Ο συνολικός χρόνος που πέρασε ήταν 0,1 δευτερόλεπτα. Ο βρόχος1 έλαβε κατά μέσο όρο το 89% του χρόνου της CPU κατά τη διάρκεια του συνολικού χρόνου που πέρασε.

Το αναποτελεσματικό πρόγραμμα loop2 χρειάστηκε τρεις φορές περισσότερο για να εκτελεστεί. Ο συνολικός χρόνος που έχει περάσει είναι 0,3 δευτερόλεπτα. Η διάρκεια του χρόνου επεξεργασίας στη λειτουργία χρήστη είναι 0,29 δευτερόλεπτα. Τίποτα δεν εγγράφεται για τη λειτουργία πυρήνα. Το loop2 έλαβε κατά μέσο όρο το 96% του χρόνου CPU για τη διάρκεια της εκτέλεσης του.

Μορφοποίηση της εξόδου

Μπορείτε να προσαρμόσετε την έξοδο από καιρό χρησιμοποιώντας μια συμβολοσειρά μορφής. Η συμβολοσειρά μορφής μπορεί να περιέχει προσδιοριστές κειμένου και μορφής. Η λίστα των προσδιοριστών μορφής μπορεί να είναι βρέθηκαν στη σελίδα man για ώρα. Κάθε ένας από τους προσδιοριστές μορφής αντιπροσωπεύει μια πληροφορία.

Όταν εκτυπώνεται η συμβολοσειρά, οι προσδιοριστές μορφής αντικαθίστανται από τις πραγματικές τιμές που αντιπροσωπεύουν. Για παράδειγμα, ο προσδιοριστής μορφής για το ποσοστό της CPU είναι το γράμμα P . Για να υποδείξετε στον χρόνο ότι ένας προσδιοριστής μορφής δεν είναι απλώς ένα κανονικό γράμμα, προσθέστε ένα σύμβολο ποσοστού σε αυτό, όπως %P . Ας το χρησιμοποιήσουμε σε ένα παράδειγμα.

Η επιλογή -f (συμβολοσειρά μορφής) χρησιμοποιείται για να πει στον χρόνο ότι αυτό που ακολουθεί είναι μια συμβολοσειρά μορφοποίησης.

Η συμβολοσειρά μας θα εκτυπώσει τους χαρακτήρες "Program:" και το όνομα του προγράμματος (και τυχόν παραμέτρους της γραμμής εντολών που μεταβιβάζετε στο πρόγραμμα). Ο προσδιοριστής μορφής %C σημαίνει "Όνομα και ορίσματα γραμμής εντολών της εντολής που χρονομετρείται". Το n κάνει την έξοδο να μετακινηθεί στην επόμενη γραμμή.

Υπάρχουν πολλοί προσδιοριστές μορφών και κάνουν διάκριση πεζών-κεφαλαίων, οπότε βεβαιωθείτε ότι τους εισάγετε σωστά όταν το κάνετε μόνοι σας.

Στη συνέχεια, θα εκτυπώσουμε τους χαρακτήρες "Συνολικός χρόνος: " ακολουθούμενος από την τιμή του συνολικού χρόνου που έχει παρέλθει για αυτήν την εκτέλεση του προγράμματος (που αντιπροσωπεύεται από %E).

Χρησιμοποιούμε το n για να δώσουμε μια άλλη νέα γραμμή. Στη συνέχεια, θα εκτυπώσουμε τους χαρακτήρες “User Mode(s)”, ακολουθούμενο από την τιμή του χρόνου CPU που δαπανήθηκε σε λειτουργία χρήστη, που υποδηλώνεται από το %U.

Χρησιμοποιούμε το n για να δώσουμε μια άλλη νέα γραμμή. Αυτή τη φορά προετοιμαζόμαστε για την τιμή χρόνου του πυρήνα. Εκτυπώνουμε τους χαρακτήρες “Kernel Mode (s)”, ακολουθούμενο από τον προσδιοριστή μορφής για τον χρόνο της CPU που δαπανάται σε λειτουργία πυρήνα, που είναι %S.

Τέλος, θα εκτυπώσουμε τους χαρακτήρες "nCPU: " για να μας δώσετε μια νέα γραμμή και τον τίτλο για αυτήν την τιμή δεδομένων. Ο προσδιοριστής μορφής %P θα δώσει το μέσο ποσοστό του χρόνου CPU που χρησιμοποιείται από τη χρονομετρημένη διαδικασία.

Ολόκληρη η συμβολοσειρά μορφής είναι τυλιγμένη σε εισαγωγικά. Θα μπορούσαμε να συμπεριλάβουμε μερικούς χαρακτήρες t για να τοποθετήσουμε καρτέλες στην έξοδο, αν ήμασταν φασαριόζοι σχετικά με την ευθυγράμμιση των τιμών.

time -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1

Αποστολή της εξόδου σε αρχείο

Για να διατηρείτε αρχείο των χρονισμών από τις δοκιμές που έχετε πραγματοποιήσει, μπορείτε να στέλνετε τα αποτελέσματα από καιρό σε ένα αρχείο. Για να το κάνετε αυτό χρησιμοποιήστε την επιλογή -o (έξοδος). Η έξοδος από το πρόγραμμά σας θα εξακολουθεί να εμφανίζεται στο παράθυρο του τερματικού. Είναι μόνο η έξοδος από το χρόνο που ανακατευθύνεται στο αρχείο.

Μπορούμε να εκτελέσουμε ξανά τη δοκιμή και να αποθηκεύσουμε την έξοδο στο αρχείο test_results.txt ως εξής:

time -o test_results.txt -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop1
cat test_results.txt

Η έξοδος του προγράμματος loop1 εμφανίζεται στο παράθυρο του τερματικού και τα αποτελέσματα από το χρόνο πηγαίνουν στο αρχείο test_results.txt.

Εάν θέλετε να καταγράψετε το επόμενο σύνολο αποτελεσμάτων στο ίδιο αρχείο, πρέπει να χρησιμοποιήσετε την επιλογή -a (προσάρτηση) ως εξής:

time -o test_results.txt -a -f "Program: %CnTotal time: %EnUser Mode (s) %UnKernel Mode (s) %SnCPU: %P" ./loop2
cat test_results.txt

Θα πρέπει τώρα να είναι προφανές γιατί χρησιμοποιήσαμε τον προσδιοριστή μορφής %C για να συμπεριλάβουμε το όνομα του προγράμματος στην έξοδο από τη συμβολοσειρά μορφοποίησης.

Και είμαστε εκτός χρόνου

Πιθανώς η πιο χρήσιμη για προγραμματιστές και προγραμματιστές για τη λεπτομερή ρύθμιση του κώδικά τους, η εντολή time είναι επίσης χρήσιμη για όποιον θέλει να ανακαλύψει περισσότερα για το τι συμβαίνει κάτω από την κουκούλα κάθε φορά που εκκινείτε ένα πρόγραμμα.