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