Fortran: Timing Code Execution

the really easy "i just want to measure my code"-way

·

3 min read

Every now and then when learning a new (or old) programming language one wants to time how long a certain function, method, algorithm or any other part of a program runs. I started looking into Fortran and I couldn’t find any easy copy-paste solution to just about do that, so I made one. (it's at the bottom if you're just looking for that)

Depending on where you look, there's lots of solutions to choose from. For example CPU_TIME or system_clock and lots of others that depend on c-Wrappers or other headers.

If you're just starting out with Fortran and are overwhelmed by all those choices, what they mean, what they're good for and really really just want to time some sorting algorithms or something, I recommend to use date_and_time. I don't know why this doesn't come up more often when searching for this, because every other way is either too complex for beginners or comes with unnecessary caveats when trying to get started.

Here's what you need:

    integer :: now(8)

    call date_and_time(values=now)

(the syntax highlighting in Hashnode really doesn't work for Fortran, huh..)

That's basically it. When calling it, the array 'now' will be filled with the current year, month, day, time difference with UTC in minutes and most importantly with hours, minutes, seconds and milliseconds.

Accessing them for outputting is easy:

    now(6)    ! minutes
    now(7)    ! seconds
    now(8)    ! milliseconds

So, assuming you wrote some kind of linear code and really just want to see where the time difference is between calling your code and your code finishing, you can simply create 3 arrays and calculate the difference:

    integer :: now(8), then(8), difference(8)
    real :: time_mseconds

    call date_and_time(values=now)

    ! YOUR CODE HERE

    call date_and_time(values=then)

    ! subtract the old values in now from the new values in then
    difference = then - now

    ! time in milliseconds
    time_mseconds = difference(6) * 60000 + difference(7) * 1000 + difference(8)

And since maybe you really just want to copy and paste this, because it's all about your code and not really about timing it, here's a complete subroutine:

! Subroutine to calculate elapsed time between two calls of date_and_time()
! time_seconds  : variable for output, time in milliseconds
! start         : integer(8) - input array from a previous date_and_time()-call
!!
subroutine elapsed_time(time_mseconds, start)
    implicit none
    ! variables
    integer :: now(8), difference(8)
    integer, intent(in) :: start(8)
    real, intent(out) :: time_mseconds

    ! get current date and  time
    call date_and_time(values=now)

    ! calculate the difference in seconds
    difference = now - start
    ! 6 = minutes, 7 = seconds, 8 = milliseconds
    time_mseconds = difference(6) * 60000 + difference(7) * 1000 + difference(8)
end subroutine elapsed_time

Use it like so:

    integer :: start(8)
    real :: time_used

    ! save time before sorting
    call date_and_time(values=start)

    ! execute whatever code you want to time
    call mycoolcode(here)

    ! update the time
    call elapsed_time(time_used, start)

Done. It was really helpful to me when starting to learn Fortran, so I hope it might help someone else as well. If you want an actual example you can run, there's one with sorting algorithms on my GitHub here.