How to get Bash execution time in milliseconds under Mac OS X?

27,774

Solution 1

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

Solution 2

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)'

Solution 3

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

coreutils is available with Homebrew : brew install coreutils.

Solution 4

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

Solution 5

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.

Share:
27,774

Related videos on Youtube

pacodelumberg
Author by

pacodelumberg

Updated on September 18, 2022

Comments

  • pacodelumberg
    pacodelumberg almost 2 years

    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?

    • mpy
      mpy about 11 years
      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.)
    • Kevin Versfeld
      Kevin Versfeld about 11 years
      Are you sure the internal clock resolution offers ACCURATE resolution down to the nano-second level?
  • pacodelumberg
    pacodelumberg about 11 years
    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:
  • demure
    demure about 11 years
    Well, that's annoying... (tested on wrong window) seeing same error :/
  • mpy
    mpy about 11 years
    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.
  • pacodelumberg
    pacodelumberg about 11 years
    thanks for making it clear, time works perfectly and outputs three results, but I need to specifically work with the initial and final times.
  • demure
    demure about 11 years
    @mpy That works on osx. Same out for the first 10 chars, acts differently between linux and OS X though.
  • pacodelumberg
    pacodelumberg about 11 years
    Does that mean we cannot get the nano second information using date?
  • mpy
    mpy about 11 years
    @LangerHansIslands: Related on SO: stackoverflow.com/q/16465702/2037712
  • pacodelumberg
    pacodelumberg about 11 years
    Thanks for your answer, could you please describe the ruby code above?
  • Olie
    Olie over 9 years
    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
    Olie over 9 years
    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.
  • Daniele B
    Daniele B almost 7 years
    thanks!!! That's THE solution nobody was reporting around...
  • Jonathan Cantrell
    Jonathan Cantrell about 3 years
    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.