I suggest C library function strtod
, you should get around 2.5X improvement with this. That is about as good as it can get if one is trying to have a (relatively decent and robust) portable set of code.
This is as per I wrote in this comment, “This may include perhaps replacing … sections … with optimized C”
Click for code
String to Double
use iso_c_binding, only: c_double, c_char, c_ptr, c_null_ptr, c_long
interface
function strtod( str, endptr ) result(d) bind(C, name="strtod" )
! <stdlib.h> :: double strtod(const char *str, char **endptr)
import :: c_char, c_ptr, c_double
! Argument list
character(kind=c_char,len=1), intent(in) :: str(*)
type(c_ptr), intent(inout) :: endptr
! function result
real(c_double) :: d
end function
end interface
integer,parameter :: n = 1000000 !! number of values
integer :: i
character(len=30),dimension(:),allocatable :: strings
real(c_double) :: rval, r_check
integer :: ierr
integer(c_long) :: start, finish, count_rate
type(c_ptr) :: endptr
! create a list of values to parse
allocate( strings(n) )
do i = 1, n
call RANDOM_NUMBER(rval)
write(strings(i), '(E30.16)') rval
if ( i == 1 ) r_check = rval
end do
blk_io: block
print *, "Block 1: formatted read toward string to double"
read(strings(1),fmt=*,iostat=ierr) rval
if ( abs(rval-r_check) > epsilon(r_check) ) then
print *, "Warning: mismatch during formatted read."
exit blk_io
end if
call system_clock(start, count_rate)
do i = 1, n
read(strings(i),fmt=*,iostat=ierr) rval
end do
call system_clock(finish)
write(*,'(A30,1X,F7.4,1X,A)') 'time * : ', (finish-start)/real(count_rate,c_double), ' seconds'
end block blk_io
print *
blk_c: block
print *, "Block 2: C strtod"
endptr = c_null_ptr
rval = strtod( strings(1), endptr )
if ( abs(rval-r_check) > epsilon(r_check) ) then
print *, "Warning: mismatch during strtod."
exit blk_c
end if
call system_clock(start, count_rate)
do i = 1, n
rval = strtod( strings(i), endptr )
end do
call system_clock(finish)
write(*,'(A30,1X,F7.4,1X,A)') 'time * : ', (finish-start)/real(count_rate,c_double), ' seconds'
end block blk_c
end
Block 1: formatted read toward string to double
time * : 0.4660 secondsBlock 2: C strtod
time * : 0.1800 seconds