Note: I've seen https://stackoverflow.com/a/64315882/21728 and understand that time is not necessarily that precise. However, I'm seeing a 4× difference between the reported time and time it actually took, and I'd like to understand what's causing it on macOS – that's the point of this question.
I'm trying to compare two ways to run a binary and they report very similar time info:
$ time ../../../node_modules/.bin/quicktype --version
quicktype version 15.0.214
Visit quicktype.io for more info.
../../../node_modules/.bin/quicktype --version 0.46s user 0.06s system 110% cpu 0.474 total
$ time $(yarn bin quicktype) --version
quicktype version 15.0.214
Visit quicktype.io for more info.
$(yarn bin quicktype) --version 0.44s user 0.06s system 110% cpu 0.449 total
However, the latter feels much slower. So I've added timestamps before and after:
$ date +"%T.%3N" && time $(yarn bin quicktype) --version && date +"%T.%3N"
15:11:09.667
quicktype version 15.0.214
Visit quicktype.io for more info.
$(yarn bin quicktype) --version 0.49s user 0.06s system 108% cpu 0.513 total
15:11:11.400
Indeed, the difference between 15:11:09.667 and 15:11:11.400 is almost two seconds but time is reporting about 0.5 second. What explains this rather vast difference?
I was using the time wrong.
First, time is different from /usr/bin/time on my Mac:
time is a shell built-in (I use Zsh)
/usr/bin/time is BSD time
This gives the expected results:
$ /usr/bin/time bash -c '../../../node_modules/.bin/quicktype --version'
quicktype version 15.0.214
Visit quicktype.io for more info.
0.49 real 0.47 user 0.06 sys
$ /usr/bin/time bash -c '$(yarn bin quicktype) --version'
quicktype version 15.0.214
Visit quicktype.io for more info.
2.02 real 1.92 user 0.27 sys
Generally speaking, for an external command cmd, it is the case that shell expansions are done by the shell before cmd is started. This includes command substitution cmd $(other_cmd), globbing cmd *.txt, variable expansion cmd $FOO, and so forth. So cmd is executed with the result of the expansion as its arguments, and never sees the original command line typed by the user.
Thus if time were an ordinary external command, as it is if you use /usr/bin/time, then the command yarn bin quicktype would be run before time even starts, and it would be just as if you had run time .../quicktype --version. It only measures the time taken to execute .../quicktype --version, and it would not (and could not) account for the time taken for the shell to generate that command line by running yarn.
Now the situation here is not quite that simple because time is actually a builtin command in many shells, and not an external command. So it doesn't necessarily have to follow the above behavior. However, in my tests, zsh's builtin time behaves the same, and does not count the time taken to run the substituted command yarn. On the other hand, in bash, the time builtin does include it.
As you saw, you can circumvent the issue by timing the running of a new shell which does both the command substitution (running yarn) and the resulting ../quicktype command itself. Then you will definitely include the time taken by both steps.
Related
Is there a way to determine (in bash) how much time is remaining on a process that is running for a specified time?
For example, some time after executing
caffeinate -s -t 8000 &
is there a command or technique for determining when my system will be allowed to sleep?
Bash won't know that caffeinate has a timer attached to it; for all it knows, -t refers to the number of times you'll place an Amazon order of Red Bull before the process exits five minutes later.
If you know this, however, you can detect when the command was started and do the math yourself.
$ sleep 45 &
[1] 16065
$ ps -o cmd,etime
CMD ELAPSED
sleep 45 00:03
ps -o cmd,etime 00:00
/bin/bash 6-21:11:11
On OS X, this will be ps -o command,etime; see the FreeBSD ps man page or Linux ps docs for details and other switches/options.
I was wondering if there is the way to get time in milliseconds from shell script on Mac OS.
I need it to time how much certain query runs.
Now I can only get the time in seconds:
Start=`date +%s`
End =`date +%s`
Time=$Start-$End
You could use the benchmarking-tool hyperfine (https://github.com/sharkdp/hyperfine).
It is more elaborate than time, by default runs your command multiple times and gives you mean runtime, deviation, min, and max.
Simple usage
hyperfine your_command
Result looks like this (result of hyperfine 'sleep 0.5'):
bash-3.2$ hyperfine 'sleep 0.5'
Benchmark #1: sleep 0.5
Time (mean ± σ): 505.6 ms ± 1.5 ms [User: 0.8 ms, System: 1.2 ms]
Range (min … max): 503.1 ms … 508.8 ms 10 runs
There is one caveat, the minimum number of runs is 2 (hyperfine -r 2 'your command').
Installation
Hyperfine can be installed via Homebrew:
brew install hyperfine
For more info see: https://github.com/sharkdp/hyperfine#on-macos
just use the 'time' command:
time something
something could be a shell, or a command (find, etc)
the "real" time is the total elapsed time you want, and includes milliseconds
Since Mac OS is BSD-like system, its date does not support the %N parameter you need.
You could though consider installing the GNU Core Utils.
It will allow you to get the time in the usual Linux way.
I suppose, the time something command will also output the result with milliseconds then.
How is it possible to display the time taken to convert a video using FFMPEG ?
i am using the below command and the time returned as benchmark is not exactly the time taken to complete the conversion.. i am confused how can it be missing in a such nice tool.
ffmpeg -cpuflags -sse-sse2-sse3-sse3slow-sse4.1-sse4.2+mmx -i E:/MSC/test.flv ^
-benchmark E:/MSC/testmmx.mp4
If you can use Bash it has the time command
time: time [-p] pipeline
Report time consumed by pipeline's execution.
Execute PIPELINE and print a summary of the real time, user CPU time,
and system CPU time spent executing PIPELINE when it terminates.
Example
$ time ffmpeg -i infile outfile
real 0m3.682s
user 0m0.015s
sys 0m0.000s
I offer Cygwin for Windows, which includes Bash and time
bitbucket.org/svnpenn/a/downloads
I Have a shell script which uses couple of system calls (grep,ps etc). I need to find CPU utilization for each system call used inside a script. I am using AIX unix version 5.1.Please help.
I have already tried Topas, vmstat , iostat commands, but they display overall cpu utilization of processes.
use below commnad
ps -aef | grep "process_name"
there would be a column 'C' in ouptut, which display cpu utilization for that process.
Thanks,
Gopal
I'm not sure if it's available on AIX, but on Linux the time command is what you would use
time wc /etc/hosts
9 26 235 /etc/hosts
real 0m0.075s
user 0m0.002s
sys 0m0.004s
sys is the amount of system call time, user is not system call time used by the process
I’d like to view information for processes running in OS X. Running ps in the terminal just lists the open Terminal windows. How can I see all processes that are running?
Say I’m running a web browser, terminal and text editor. I’d like to see information for the text editor and web browser.
Running ps -e does the trick. Found the answer here.
You can just use top
It will display everything running on your OSX
Using top and ps is okay, but I find that using htop is far better & clearer than the standard tools Mac OS X uses. My fave use is to hit the T key while it is running to view processes in tree view (see screenshot). Shows you what processes are co-dependent on other processes.
You can install it from Homebrew using:
brew install htop
And if you have Xcode and related tools such as git installed on your system and you want to install the latest development code from the official source repository—just follow these steps.
First clone the source code from the htop GitHub repository:
git clone git#github.com:hishamhm/htop.git
Now go into the repository directory:
cd htop
Run autogen.sh:
./autogen.sh
Run this configure command:
./configure
Once the configure process completes, run make:
make
Finally install it by running sudo make install:
sudo make install
Try ps -ef. man ps will give you all the options.
-A Display information about other users' processes, including those without controlling terminals.
-e Identical to -A.
-f Display the uid, pid, parent pid, recent CPU usage, process start time, controlling tty, elapsed CPU usage, and the associated command. If the -u option is also used, display
the user name rather then the numeric uid. When -o or -O is used to add to the display following -f, the command field is not truncated as severely as it is in other formats.
Try the top command. It's an interactive command that will display the running processes.
You may also use the Apple's "Activity Monitor" application (located in /Applications/Utilities/).
It provides an actually quite nice GUI. You can see all the running processes, filter them by users, get extended informations about them (CPU, memory, network, etc), monitor them, etc...
Probably your best choice, unless you want to stick with the terminal (in such a case, read the top or ps manual, as those commands have a bunch of options).
To sort by cpu usage: top -o cpu
if you are using ps, you can check the manual
man ps
there is a list of keywords allowing you to build what you need. for example to show, userid / processid / percent cpu / percent memory / work queue / command :
ps -e -o "uid pid pcpu pmem wq comm"
-e is similar to -A (all inclusive; your processes and others), and -o is to force a format.
if you are looking for a specific uid, you can chain it using awk or grep such as :
ps -e -o "uid pid pcpu pmem wq comm" | grep 501
this should (almost) show only for userid 501. try it.
The slightly GUI way
if you are a cli (ui) fan. I recommend trying https://github.com/clementtsang/bottom which shows not only processes, but also temperature, disk usage and network. Screenshot is running from kitty (terminal) as an example, I use it on OSX default terminal and the color shows up a bit different, but still amazing.
The tree way
As described here : https://en.wikipedia.org/wiki/Pstree will give a better connection on the hierarchy of the processes
brew install pstree # if you need to install it
pstree
pstree -u <user> # show only processes by your user
pstree -s <string> # show only processes with string
pstree -help # show help