Bash Shell

Want to analyze how much wall clock time, kernel time, etc., a Linux program takes to run? Whether for performance testing, code optimization, or just general curiosity, this quick guide will get you started!

Timing Linux Programs

Timing a Linux program helps one to understand how much time was spent. The versatile Linux time command can be used for this. The time command measures real (i.e. wall clock time), user, and sys time. User time is the time the program runs in user-mode, or in other words, outside of the kernel. The sys time is the time the program runs inside the kernel.

It is important to note that both user time and sys time are actual CPU time spent inside user-mode and inside the kernel, respectively. In other words, when a program is blocked for a while and is not using the CPU, such time will not count towards user or sys times. Knowing this, we can accurately measure how much effective CPU time was used (by combining them).

The Linux time Tool

Given that user and sys times report CPU time only, whereas real time reports actual wall clock time, it is (thus) very common to see the time tool return output where a combination of user + sys does not equal real time. An example can be seen when timing sleep:

time sleep 1

A simple time command testing the time taken by a sleep 1 command at the Linux command prompt

Here we timed the sleep command using the time tool. As we can see, our real time (1.001 seconds) matches our wall clock time, and requested time (sleep 1 requests a sleep of one second) very well. We also see that extremely little CPU time had to be spent on the command as a whole: combining user + sys time, we see that only 0.001 seconds were spent.

We can also, likely incorrectly, deduce that the kernel was not involved in this command, as the sys time is effectively 0. However, as the time manual states: “When the running time of a command is very nearly zero, some values (e.g., the percentage of CPU used) may be reported as either zero (which is wrong) or a question mark.”

Using time For Performance Measuring

We can use time to evaluate how long given actions will take (i.e., wall clock time) and how much CPU time they consumed while doing so. As a simple example, we could evaluate if any file system cache is operating on our system. To do so, we could jump into the /usr directory, which could easily hold 200k to 500k files on a commonplace Linux installation.

Once there, we can use the find tool, timed by time to evaluate how long it would take to scan through all folders and list all files in the /usr directory:

cd /usr
time find . >/dev/null 2>&1

Listing the contents of /usr with find and timing the same

As we can see, it takes 12.484 seconds to list all files in the /usr directory (and below it). We redirected the stdout output (standard output) of the command to >/dev/null and also redirect any stderr errors (standard error) to /dev/null by using a redirect from stderr to stdout, i.e. 2>&1.

We also see that our CPU time is 1.043 seconds (user) + 2.908 seconds (sys) for a total of 3.951 seconds of CPU time.

Let’s test it another time by clearing our inode (and other) cache(s):

sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
cd /usr
time find . >/dev/null 2>&1

Clearing the inode (and other) Linux caches and re-executing our find command in /usr

The first command will drop the inodes cache, dentries (directory entries), and pagecache. This time the result came back a little quicker, with 1.255 seconds saved on the command. Likely a physical disk-based cache helped here.

To demonstrate how well Linux caching works in general, let’s re-run the command but this time without dropping the Linux caches:

Re-executing the find command without clearing the caches results in much faster execution

Quite a difference! We see a large reduction in required time in all three timed areas and our command executes in less than half a second!

Using time For Code Optimization

Once we feel comfortable using the time command at the command line, we can expand its use to optimize our Bash scripts and code. For example, one commonly used approach amongst some professionals is to run a given command many times, like 1000 runs, and calculate the total (or average) time of these runs.

Then, an alternative command can be used. That alternative command (or solution/implementation – i.e., multiple commands taken together as a single piece of code to be timed) can then be timed again. In Linux (or more specifically in Bash coding etc.), there are often many ways to approach a given problem; there are usually multiple tools available to obtain/achieve the same result.

Testing which one performs best optimizes program run time and potentially other factors like disk I/O (reducing disk wear) or memory utilization (allowing more programs to execute on the same instance). For optimizing the wall clock time, a certain tool uses, on average, as well as the CPU time consumed by the tool (another important optimization factor/consideration) can be measured by the time tool.

Let’s explore a practical example of using the command line to execute a command we want to use in one of our scripts. The command will obtain a process list and display the second column. We use both awk and sed to do so, and run each command 1000 times to see the difference in performance overall.

time for ((i=1;i<=1000;i++)); do ps -ef | awk '{print $2}' >/dev/null 2>&1; done
time for ((i=1;i<=1000;i++)); do ps -ef | sed 's|^[^ ]+[ t]+||;s|[ t].*||' >/dev/null 2>&1; done

Using time to analyze the average execution time of any command, allowing one to optimize Linux script runtimes

While looking more complex (it uses a double regular expression to parse out the second column), our second command is a bit faster than our first command when it comes to wall clock time.

Using a very similar setup (i.e. time for ((i=1;i<=1000;i++)); do command_to_be_timed >/dev/null 2>&1; done where command_to_be_timed is the command to be tested for wall clock or CPU time), one can time-test any command, or set of commands (as is the case here; we used both the ps and awk/sed commands).

Taking these steps for several time-consuming commands (in any Linux script) will help us to reduce the overall run time and/or (if you optimize towards reduced CPU time) the system load of our scripts.

If you want to learn more about regular expressions, How to Modify Text Using Regular Expressions With the sed Stream Editor is likely of interest.

Wrapping up

In this article, we explored the Linux time command. We clarified what real, user and sys times indicate and how the latter two relate to CPU usage. We also reviewed several examples of how to use time in practical ways.

If you enjoyed reading this article, have a look at Asserts, Errors, and Crashes: What’s the Difference? and What is Stack Smashing? Can it be Fixed?.

Profile Photo for Roel Van de Paar Roel Van de Paar
Roel has 25 years of experience in IT & business, 9 years of leading teams, and 5 years in hiring & building teams. He worked for companies like Oracle, Volvo, Sun, Percona, Siemens, Karat, and now MariaDB in various senior, principal, lead, and managerial roles.
Read Full Bio »