So it seems that Fortran is not so popular these days and there is a reason for that. Through the years, newer programming languages like Python have adapted to the overall evolution of computer science and had the chance of being developed in a time with more mature operating systems and hardware.

So today, Python is a well-designed language with a reasonably clean syntax, a comprehensive standard library, excellent included and third party documentation, widespread deployment, and the immediacy of a “scripting” style language (ie. no explicit compile step).

It is true that for some specific tasks, like the handling of strings, Fortran seems quite outdated comparing to Python. However for some certain tasks like lengthy numerical calculations there is a general belief that Fortran still has the lead. But to what extent is Fortran better for such tasks? How we may give a quantitative answer to such a question?

In a previous post for the purpose of comparing Fortran compilers, we have used a simple small algorithm (the Sieve of Eratosthenes) for finding prime numbers. Here the code is re-written in Python and it follows exactly the same logic as the code in Fortran, almost line-by-line. Check the two following blocks of code…

**Fortran code**

program primes implicit none integer, parameter :: max=10000000 ! Search for primes up to 10^7 integer :: i, j, k, product(max), imax, jmax, numprime do k=1,100 ! 100 iterations of the calculation do i = 1, max product(i) = 0 enddo numprime=0 imax = floor(sqrt(real(max))) do i = 2, imax if (product(i) == 0) then jmax = max/i do j = 2, jmax product(i*j) = 1 enddo end if end do do i = 2, max if (product(i) == 0) then numprime = numprime + 1 end if enddo print *, 'Number of primes = ',numprime enddo end program primes

**Python code**

max=10000000 for k in range(1, 101): product = [0] * (max + 2) numprime=0 imax = int(round(max**0.5)) for i in range(2, imax+1): if product[i] == 0: jmax = int(max/i) for j in range(2, jmax+1): product[i*j]=1 for i in range(2, max+1): if product[i] == 0: numprime=numprime+1 print 'number of primes = ',numprime product[:] = []

Admittedly the python code is a bit more elegant than the corresponding fortran code (depending of course on how you perceive elegance…). But what about the speed of execution? Well it appears that on an early 2011 Macbook Pro (2.3GHz core i5, 4GB RAM 1333MHz DDR3) and Python version 2.7.5 it takes 800 seconds (something a bit less than 14min!!!) to repeat for a hundred times the search of prime numbers up to 10^7. Well that is freaking too much! The Fortran executable (compiled with gfortran v. 4.8.1) took 16.5 seconds in total for the same task. That means that for this particular example, **Fortran is about 48 times faster than Python!!!** Surprisingly my trial to modify the python code and use a numpy matrix instead of a list, lead to even higher execution time. After the suggestion of a reader, I ran the same test with PyPy (version 2.2.1) instead of pure Pyhton. So with PyPy the calculation takes 50 seconds. Quite an improvement comparing to pure Python but still around 3 times slower than Fortran.

Someone might say that this is not a fair comparison since we have to do with an interpreted vs a compiled language. In any case this impressive difference reminds us that at least for parts of code that are slow and have extensive looping, interfacing python with Fortran has clear advantages! In the near future we will come back to the subject of interfacing Fortran and python code.

For the moment keep in mind that Fortran was developed back in an era where hardware was quite primitive and execution speed very important. In fact it was the first high-level language at all and its creators had to convince the community of Assembly programmers that Fortran can create machine code that is nearly as good as their hand crafted Assembly programs. This very important benefit is still inherited by Fortran today, and it really makes a difference.

Jason SEver try using the [Numba](http://numba.pydata.org/) library?

fortranerPost authorI will give it a try… do you have an estimation how faster in general the executables would be comparing to PyPy?

JakeHi, I came across your page and I had to comment on your code. You’d do well to make yourself more familiar with the features of Fortran, in this case, scalar assignments, masked assignments, and built-in functions. Take a look at the following:

program primes

implicit none

integer, parameter :: max = 10000000

integer :: i, j, k, imax, jmax, numprime

logical :: prod(max) ! product is the name of a built-in function

do k = 1, 100

prod(:) = .TRUE. ! scalar assignment eliminates do loop

numprime = 0

imax = floor(sqrt(real(max)))

do i = 2, imax

if (prod(i)) then

jmax = max/i

prod(2*i:i*jmax:i) = .FALSE. ! masked assignment eliminates do loop

end if

end do

print *, ‘Number of primes = ‘, count(prod)-1 ! built-in count function eliminates do loop

end do

end program primes

JakeSilly me, can improve this even more:

program primes

implicit none

integer, parameter :: pmax = 10000000 ! max is a built-in function too

integer :: i, k, imax

logical :: prod(pmax) ! product is the name of a built-in function

do k = 1, 100

prod(:) = .TRUE. ! scalar assignment eliminates do loop

imax = floor(sqrt(real(pmax)))

do i = 2, imax

if (prod(i)) then

prod(2*i:pmax:i) = .FALSE. ! masked assignment eliminates do loop

end if

end do

print *, ‘Number of primes = ‘, count(prod)-1 ! built-in count function eliminates do loop

end do

end program primes