【发布时间】:2013-06-23 06:34:26
【问题描述】:
我正在读取一个包含 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)
*********编辑******
感谢您的 cmets。我不确定如何在 fortran 中执行此操作。我尝试了以下方法,但这仍然很慢。
flag = np.ndarray(length, dtype=np.bool)
for index in range(length):
if (data[index] >= threshold):
flag[index] = 1
else:
flag[index] = 0
谁能给我看看?
【问题讨论】:
-
您是否尝试过预先分配您的标志 []? IE。使用 np.ndarray(5123, dtype=np.bool) 而不是列表。数组具有随机访问权限,因此您需要 O(1) 时间来访问(整个周期需要 O(n) 时间),而对于列表,您需要 O(n) 时间来访问 1 个元素(并且 O(n2)完全)。
-
这是正常的。 Python 通常比 Fortran 之类的编译语言慢得多(但更灵活)。对于这样的计算,您可以尝试 numpy 的高级功能(但我错问细节)。
-
@AlexanderMihailov 感谢您的评论。但我不确定如何实施您的建议。我已经编辑了我的帖子以说明我尝试过的内容,但它并没有改变性能。
-
我建议您谨慎对待您正在尝试做的事情。当然,您总是可以将 python 代码优化到极致(在极端情况下,它永远不会像 Fortran 一样快——如果您想知道为什么,那是另一个问题)。但是在那些极端情况下……您首先会失去很多使用 python 的优势;它的语言范式以自己独特的方式使代码更具表现力。当您与该语言的设计使用方式作斗争时,您应该考虑使用专门针对您的需求而设计的其他语言。