18

I've checked this, but the solution provided did not work for me.

Using date I can get the execution time in seconds:

T="$(date +%s)"
#some work here
T="$(($(date +%s)-T))"
echo "execution time (secs) ${T}"

However, when I try this:

T="$(date +%s%N)"
#some work here
T="$(($(date +%s%N)-T))"

Adding %N (as above) to the date to get the nano-second precision I get the following error: -bash: 1369320760N: value too great for base (error token is "1369320760N")

Does anyone know how to measure the execution time in milliseconds using bash under Mac OS X?

2
  • Do you really need nano second resolution? Which this approach you have a lot of overhead. With # some work here ommited, I get times from 0.2 to 0.3 sec -- what should be zero (or at least constant) to reach your goal. Whereas /usr/bin/time usleep 50000 gives a reasonale stable time of 0.05 +/- 0.01 sec. (Only tested in Linux, don't know if /usr/bin/time and/or usleep is available on OSX.)
    – mpy
    May 23, 2013 at 15:18
  • Are you sure the internal clock resolution offers ACCURATE resolution down to the nano-second level?
    – mdpc
    May 23, 2013 at 17:14

6 Answers 6

19

Since OSX is a BSD-ish system, it's strftime library doesn't have %N (http://www.freebsd.org/cgi/man.cgi?query=date)

Does the bash builtin time command give you information you need?

time some work here
1
  • 2
    thanks for making it clear, time works perfectly and outputs three results, but I need to specifically work with the initial and final times. May 23, 2013 at 15:16
15

I would go this route if I needed milliseconds and BSD didn't support date +%s%N

perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)'
3
  • thanks!!! That's THE solution nobody was reporting around...
    – Daniele B
    Sep 21, 2017 at 10:56
  • and this also works in most unix systems since Perl is available by default in most distributions. But its not as cheap as using date or EPOCHREALTIME
    – Deepu
    Oct 16, 2023 at 16:19
  • and this also works in most unix systems since Perl is available by default in most distributions. But its not as cheap as using date or EPOCHREALTIME
    – Deepu
    Oct 16, 2023 at 16:19
8

If you install coreutils you can use the GNU Linux date by writing gdate.

coreutils is available with Homebrew : brew install coreutils.

1
  • Also, per this answer, running brew info coreutils provides you with the command to add to your shell's startup script to load the gnu utilities first. Apr 15, 2021 at 18:44
3

echo $(($(date +%s%N)/1000000))

This would convert from nano-seconds to milli-seconds.

From @mpy, date +%s.%N works.

Output is different between linux and OS X though:
linux: 1369322592.573787111
OS X: 1369322610.N

7
  • I am getting the following error: -bash: 1369321446N: value too great for base (error token is "1369321446N")this does not work in mac osx, I am getting: May 23, 2013 at 15:04
  • Well, that's annoying... (tested on wrong window) seeing same error :/
    – demure
    May 23, 2013 at 15:11
  • 1
    No need to divide the output, just use date +%s.%N (but I can't check on OSX; it's working on Linux). But the problem then is, that bash's $(( )) IMHO isn't able to handle floating point numbers.
    – mpy
    May 23, 2013 at 15:14
  • @mpy That works on osx. Same out for the first 10 chars, acts differently between linux and OS X though.
    – demure
    May 23, 2013 at 15:17
  • Does that mean we cannot get the nano second information using date? May 23, 2013 at 15:57
1

As the other answer's mentioned, OS X's date doesn't support %N (nanoseconds).

Could you just save the commands to time as a script? Or use a subshell or command group for them:

time (sleep 0.1; echo a; sleep 0.1)
time { sleep 0.1; echo a; sleep 0.1; }

Or sum the times of individual commands:

$ time=$(TIMEFORMAT=%R; (time sleep 0.1; echo a) 2>&1 > /dev/null)
$ time+=+$(TIMEFORMAT=%R; (time sleep 0.1) 2>&1)
$ bc <<< $time
.206

Or use some scripting language:

$ ruby -e 'puts "%.3f" % Time.now'
1369329611.046
$ time ruby -e '""'
0.029
$ time ruby -e 'puts "%.3f" % Time.now'
1369329622.943
0.029

%.3f is a format specifier for a floating point number with 3 decimal points. Time.now is a class method of the Time class.

3
  • Thanks for your answer, could you please describe the ruby code above? May 24, 2013 at 7:22
  • 1
    In ruby -e 'puts "%.3f" % Time.now', ruby calls the ruby interpreter, -e executes the script that follows on the command line. puts is ruby's printf (sort of), Time is a ruby object and Time.now is the seconds since the epoch. Using %.3f trims the output to 3 decimal places, which is milliseconds (the ".046" and ".943" parts of the output.)
    – Olie
    Oct 16, 2014 at 16:01
  • 1
    Also, time is a command line tool that times how long it takes to run the command that follows. See man time for more details.
    – Olie
    Oct 16, 2014 at 16:02
1

Glenn is right, time is the command you are looking for, but in order to parse out the info you want, you will need to pass it along to some other processor like sed.

time command-goes-here >/dev/null 2>$1|sed rules-go-here

This command will get rid of the output from the command itself (sending both standard and error outputs to /dev/null), and pass the time results to sed, where you will need to choose the appropriate rules to edit the stream, and output the desired value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .