2016-02-05 62 views
1

我正在研究一個項目,我需要將一些現有數據寫入磁盤ascii。我有一些工作,但IO本身是非常昂貴的,我想進一步優化。優化Fortran ascii文件IO

數據基本上是實數的數組,但是某些列存儲需要重新編碼爲字符串的編碼字符串(不要問!)。這個問題的輸入和輸出超出了我的控制範圍,我正在接收這個真正的數組,並且需要將它寫爲ascii。

我知道一次寫入數組是正確的,因爲未格式化的寫入速度更快,但這不能正確處理字符串列。有任何想法嗎?

下面是一些示例代碼:

program test 
implicit none 

integer(kind=4), parameter  :: nrows = 5000 
integer(kind=4), parameter  :: ncols = 400 
integer, parameter    :: real_kind = 8 

integer(kind=4)     :: i,j, handle 
character(len=256)    :: value_str 
character(len=1)    :: delimiter 
real(kind=real_kind)   :: data(nrows,ncols) 

delimiter = " " 
data(:,:) = 999.999 

! Some examples of the "string columns" 
data(:,10) = transfer(' foo ',data(1,1)) 
data(:,20) = transfer(' bar ',data(1,1)) 

handle=10 
open(handle,file="out.txt",status="replace", access="stream") 

do i=1,nrows 
    do j=1,ncols 
     ! If this column contains encoded strings then recast 
     if((j==10).or.(j==20))then 
       write(handle) delimiter 
       value_str = transfer(data(i,j),value_str(1:real_kind)) 
       write(handle) trim(value_str) 
     else 
       write(value_str,*) data(i,j) 
       write(handle) trim(value_str) 
     endif 
    enddo 
    write(handle) new_line('x') 
enddo 
close(handle) 

end program test 

gfortran test.F90 -o test.x

時間test.x

真實0m2.65s

用戶0平方米.24s

sys 0m0.04s

編輯:從原始test.F90代碼樣本中刪除「if(j/= 1)」以迴應評論。

+0

什麼是「但這不正確地處理字符串列」。意思?數據格式的例子在哪裏? –

+0

如果您運行上面提供的test.F90代碼並查看out.txt,則可以看到數據格式。您可以將字符串讀爲「foo」和「bar」,即可讀的字符串。 –

回答

2

使用自由格式並讓系統爲您處理更多。在這個命題中,我事先處理傳輸,並使用單個循環將數據寫入文件。如果你的例子中只有幾列字符數據(如2),這很方便。

您的代碼看起來像這樣

program test 
implicit none 

    integer(kind=4), parameter  :: nrows = 5000 
    integer(kind=4), parameter  :: ncols = 400 
    integer, parameter    :: real_kind = 8 
    integer, parameter    :: pos1 = 10 ! I like named constants 
    integer, parameter    :: pos2 = 20 ! I like named constants 

    integer(kind=4)     :: i,j, handle 
    character(len=256)    :: value_str 
    character(len=1)    :: delimiter 
    real(kind=real_kind)   :: data(nrows,ncols) 
    character(real_kind), dimension(nrows,2) :: cdata ! two columns array for 

    delimiter = " " 
    data(:,:) = 999.999 

    ! Some examples of the "string columns" 
    data(:,pos1) = transfer(' foo ',data(1,1)) 
    data(:,pos2) = transfer(' bar ',data(1,1)) 

    handle=10 
    open(handle,file="out.txt",status="replace", form="formatted") 

    ! Transfer beforehand 
    cdata(:,1) = transfer(data(:,pos1), cdata(1,1)) 
    cdata(:,2) = transfer(data(:,pos2), cdata(1,1)) 
    do i=1,nrows 
     write(handle,*) data(i,1:pos1-1), cdata(i,1)& 
      , data(i,pos1+1:pos2-1), cdata(i,2)& 
      , data(i,pos2+1:) 
    enddo 
    close(handle) 
end program test 

,並給這個時機

時間./test.x

真正0m1.696s

用戶0m1.661s

sys 0m0.029s

代替

時間./test.x

真正0m2.654s

用戶0m2.616s

SYS 0m0.032s

在我的電腦上