我正在编写一个代码,用于在定义的区域中随机生成一些斑点(并存储它们的x,y坐标),并在随后的时间步长中将它们移动并生长为三角形(并存储x,y坐标)所有时间步骤的3个角落和时间)。时间步长DT约为1微秒。对于较小的时间尺度(TIME_MAX),下面的代码有效。对于大于0.005的TIME_MAX,它会在GROW功能中卡住/挂起,因为它占用大量CPU时间并且仍然不会生成所需的输出。由于它是在串行模式下运行,我想知道是否有任何方法可以加快速度 - 通过不同的循环技术或一些数组修改或其他一些优化方法。我想至少能够在CPU的标准单核上运行它直到TIME_MAX = 1。任何帮助将非常感激。提前致谢!
代码如下:
import math
import random
import numpy as np
# Initializations
####
ui = 4138
x_length = 2.0
y_width = 1.0
xtro = 0.5
ule = 3724
ute = 2069
alfa = 1.31
xsgs = xtro
xsge = xsgs + 0.1*xsgs
INDEX = 0
TIME = 0
DT = 0.000001
TIME_MAX = 1.0
GROW = []
DOTS = []
####
def init(TIME, xsgs, xsge, y_width):
PX = xsgs + random.random()*(xsge-xsgs)
PY = y_width*random.random()
TIME_FORM = TIME
DOTS.append([PX, PY, TIME_FORM])
return(DOTS[:])
def grow(INDEX, TIME, TIME_FORM, PX, PY, ute, ule, alfa):
X1 = PX + ule*(TIME-TIME_FORM)
Y1 = PY
X2 = PX + ute*(TIME-TIME_FORM)
Y2 = PY + ute*(TIME-TIME_FORM)*math.tan(alfa)
X3 = PX + ute*(TIME-TIME_FORM)
Y3 = PY - ute*(TIME-TIME_FORM)*math.tan(alfa)
if X2 < 1.5 and Y2 < 0.5 and Y3 > 0:
GROW.append([INDEX, TIME, TIME_FORM, X1, Y1, X2, Y2, X3, Y3])
return (GROW[:])
while TIME<TIME_MAX:
Y_N = random.random()
if Y_N < 0.1:
DOTS = init(TIME, xsgs, xsge, y_width)
TIME = TIME+DT
for j in range(len(DOTS)):
PX = DOTS[j][0]
PY = DOTS[j][1]
TIME_FORM = DOTS[j][2]
INDEX = TIME_FORM/DT
GROW = grow(INDEX, TIME, TIME_FORM, PX, PY, ute, ule, alfa)
DOTS = np.array(DOTS)
np.savetxt('gen_dump.txt', DOTS, fmt = '%10.12f', delimiter=',', newline = ';\n', header='data =[...', footer=']', comments = '#')
GROW = np.array(GROW)
np.savetxt('grow_dump.txt', GROW, fmt = '%10.12f', delimiter=',', newline = ';\n', header='data =[...', footer=']', comments = '#')
print(DOTS)
print(GROW)
答案 0 :(得分:2)
优化功能增长的一种方法: “math.tan”:python解释器搜索两次这个全局,也必须访问数学而不是tan。 你可以写一个本地Tan并将其设置为math.tan。
Simliar to ule *(TIME-TIME_FORM)此操作完成5次
def grow(INDEX, TIME, TIME_FORM, PX, PY, ute, ule, alfa):
tmp = ule*(TIME-TIME_FORM)
TanAlfa = math.tan(alfa)
X1 = PX + tmp
Y1 = PY
X2 = X1
Y2 = PY + TanAlfa
X3 = X1
Y3 = PY - TanAlfa
if X2 < 1.5 and Y2 < 0.5 and Y3 > 0:
GROW.append([INDEX, TIME, TIME_FORM, X1, Y1, X2, Y2, X3, Y3])
return (GROW[:])
答案 1 :(得分:1)
您在每次迭代时重新复制DOTS
和GROW
,然后重新分配它。随着列表的增长,复制操作(GROW[:]
)可能会花费很多,而且似乎并不需要它。只需追加价值,不做任何其他事情。例如GROW
def grow(INDEX, TIME, TIME_FORM, PX, PY, ute, ule, alfa):
...
if X2 < 1.5 and Y2 < 0.5 and Y3 > 0:
GROW.append([INDEX, TIME, TIME_FORM, X1, Y1, X2, Y2, X3, Y3])
# no return needed
并且
for j in range(len(DOTS)):
...
INDEX = TIME_FORM/DT
grow(INDEX, TIME, TIME_FORM, PX, PY, ute, ule, alfa)
DOTS
也是如此。
答案 2 :(得分:0)
另一个小改进是使用xrange而不是range。在这里你可以阅读更多: https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Use_xrange_instead_of_range