As you have already seen, formatted reads and writes of real numbers are expensive. Here are a pair of simple tests that involve almost no external I/O and make the point. No need to consider SSDs, Ramdisks, etc.
In the first example, I use a string variable containing one line similar to the lines generated in John's tests. I then read the ten real numbers using 10F10.3 as the format. I repeat this READ 1 million times, and write to the console after 100000, 200000, etc., 1000000 iterations. This WRITE is necessary to prevent the optimization phase of the compiler from making the whole loop vanish.
program FmtRead
implicit none
character(len=100) :: str
integer :: i,j
real, dimension(10) :: x
write(str,'(10F10.3)')(3.0*i-7.679,i=1,10)
do j=1,1000000
read(str,'(10F10.3)')x
if(mod(j,100000).eq.0)write(*,*)j,x(3)
end do
end program
This program, compiled with gFortran -O2, runs in 3 seconds on a cloud Linux server.
The second program is a modified version of the first, in which the internal READ is replaced by code that directly interprets the string in Fortran code, without going through the Fortran I/O runtime. It does not check for invalid characters, missing decimal points and other similar errors -- the input string is assumed to be valid for the format in question.
program IntlRead
implicit none
character(len=100) :: str
integer :: i,j,k,n,sgn,iv,fv,tp
real, dimension(10) :: x
write(str,'(10F10.3)')(-7.679+3*i,i=1,10)
do j=1,1000000
do n=1,10
k=(n-1)*10+1
sgn=1
do while(str(k:k) == ' ')
k=k+1
end do
if(str(k:k) == '-')then
sgn=-1
k=k+1
endif
iv=0
do while(str(k:k) /= '.')
iv=iv*10+ichar(str(k:k))-ichar('0')
k=k+1
end do
k=k+1; fv=0; tp=1
do while(str(k:k) >= '0' .and. k <= n*10)
fv=fv*10+ichar(str(k:k))-ichar('0')
tp=tp*10
k=k+1
end do
x(n)=sgn*(real(iv)+real(fv)/real(tp))
end do
if(mod(j,100000).eq.0)write(*,*)j,x(3)
end do
end program
On the same system, the modified code runs in 0.3 s. Thus, the convenience of formatted input can carry a hefty price tag. In a real program, therefore, it is worthwhile to minimize formatted I/O as much as possible. If the same file is read several times in the program, it may be advantageous to put the read data into memory during the first file reading and replace the subsequent file reads by memory copying.