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?

  • 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 '13 at 15:18
  • Are you sure the internal clock resolution offers ACCURATE resolution down to the nano-second level? – mdpc May 23 '13 at 17:14

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
| improve this answer | |
  • 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. – pacodelumberg May 23 '13 at 15:16

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)'
| improve this answer | |
  • thanks!!! That's THE solution nobody was reporting around... – Daniele B Sep 21 '17 at 10:56

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

coreutils is available with Homebrew : brew install coreutils.

| improve this answer | |

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

| improve this answer | |
  • 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: – pacodelumberg May 23 '13 at 15:04
  • Well, that's annoying... (tested on wrong window) seeing same error :/ – demure May 23 '13 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 '13 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 '13 at 15:17
  • Does that mean we cannot get the nano second information using date? – pacodelumberg May 23 '13 at 15:57

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

Or use some scripting language:

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

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

| improve this answer | |
  • Thanks for your answer, could you please describe the ruby code above? – pacodelumberg May 24 '13 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 '14 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 '14 at 16:02

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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.