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.
Related
I'm aware that I can use time as
time <some command>
But this requires me to remember to type time before <some command>
I'm wondering if it's possible create some sort of hook, so that time is run for every command, but only displayed if I enter last-time or something at the cli.
An example usage might be:
$ sleep 2
$ last-time
________________________________________________________
Executed in 2.00 secs fish external
usr time 2.28 millis 912.00 micros 1.37 millis
sys time 0.30 millis 296.00 micros 0.00 millis
The $CMD_DURATION variable contains the duration of the last-run interactive command, in milliseconds.
$ sleep 2
$ echo $CMD_DURATION
2014
Docs are here.
I want to print the cpu% of one running process every seconds in the terminal.
In addition to the cpu%, I would like to print the corresponding time stamps as well.
Example:
$
13:00:00 34,0%
13:00:01 35,2%
13:00:02 36,1%
What would be best approach for this?
Remark:
top -pid PID -s 1
Executing this command is close to what I want to achieve, except that:
It will update the output on one single line, and won't print new lines every second.
It will not print system time stamps.
I am using zsh shells in macOS.
Computer: MacBook Pro (16-inch, 2019)
Processor: 2,6 GHz 6-Core Intel Core i7
Memory: 16 GB 2667 MHz DDR4
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.
Can I configure bash to report how long each command takes to execute, if it's longer than some threshold?
I thought I recalled some setting for this, but can't find it either in bash(1) or google.
The idea, in case it's not clear, would be something like this:
% SUBCMDTMOUT=30
% sleep 29 # 29 seconds elapse
% sleep 30 # 30 seconds elapse
% sleep 31 # 31 seconds elapse
bash: subcommand `sleep 31' took 31 seconds to complete.
%
Prepend time to your command and then parse the output of time through any condition to get your desired output.
Example:
$ time sleep 15
real 0m15.003s
user 0m0.000s
sys 0m0.002s
#chepner probably has it right: REPORTTIME in zsh (though that only tracks CPU time; I suspect my mystery problem is some kind of network wait). But since I'm not motivated enough to convert my login shell for this, the specific answer to my question is "nope."
I want to be able to do the Windows equivalent of this Unix/Linux command:
time fooenter code here
foo
x cpu time
y real time
z wallclock time
timeit from the Windows Server 2003 Resource Kit should do the trick.