对于一个小程序,python和fortran差异的巨大差异

时间:2013-06-26 08:03:11

标签: python fortran

我正在读取一个包含512 ** 3数据点的单精度数据的文件。基于一个阈值,我为每个点分配一个1或0的标志。我写了两个程序做同样的事情,一个在fortran,另一个在python中。但是fortran中的那个需要0.1秒,而python中的那个需要几分钟。这是正常的吗?或者你能指出我的python程序的问题:

fortran.f

  program vorticity_tracking

  implicit none

  integer, parameter :: length = 512**3
  integer, parameter :: threshold = 1320.0

  character(255) :: filen
  real, dimension(length) :: stored_data
  integer, dimension(length) :: flag
  integer index

  filen = "vor.dat"

  print *, "Reading the file ", trim(filen)
  open(10, file=trim(filen),form="unformatted",
 &     access="direct", recl = length*4)
  read (10, rec=1) stored_data
  close(10)

  do index = 1, length
     if (stored_data(index).ge.threshold) then
        flag(index) = 1
     else
        flag(index) = 0
     end if
  end do

  stop
  end program

Python文件:

#!/usr/bin/env python

import struct
import numpy as np

f_type = 'float32'
length = 512**3
threshold = 1320.0
file = 'vor_00000_455.float'

f = open(file,'rb')
data = np.fromfile(f, dtype=f_type, count=-1)
f.close()

flag = []

for index in range(length):
    if (data[index] >= threshold):
        flag.append(1)
    else:
        flag.append(0)

** * ** * *** 修改 ** * ***

感谢您的评论。我不确定如何在fortran中这样做。我试过以下但这仍然很慢。

 flag = np.ndarray(length, dtype=np.bool)    
 for index in range(length):
     if (data[index] >= threshold):
         flag[index] = 1
     else:
         flag[index] = 0

有人可以告诉我吗?

3 个答案:

答案 0 :(得分:6)

你的两个节目完全不同。您的Python代码会反复更改结构的大小。您的Fortran代码没有。你不是在比较两种语言,而是在比较两种算法,其中一种算法显然是次要的。

答案 1 :(得分:3)

通常,Python是一种解释型语言,而Fortran是一种编译语言。因此,你在Python中有一些开销。但它不应该花那么长时间。

python版本中可以改进的一件事是用索引操作替换for循环。

#create flag filled with zeros with same shape as data
flag=numpy.zeros(data.shape)
#get bool array stating where data>=threshold
barray=data>=threshold
#everywhere where barray==True put a 1 in flag
flag[barray]=1

更短的版本:

#create flag filled with zeros with same shape as data
flag=numpy.zeros(data.shape)
#combine the two operations without temporary barray
flag[data>=threshold]=1

答案 2 :(得分:1)

尝试使用python:

flag = data > threshhold

它会根据你的需要为你提供一系列标志。