需要代码优化帮助,因为它在串行操作中陷入困境

时间:2014-07-03 07:24:20

标签: python loops optimization

我正在编写一个代码,用于在定义的区域中随机生成一些斑点(并存储它们的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)

3 个答案:

答案 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)

您在每次迭代时重新复制DOTSGROW,然后重新分配它。随着列表的增长,复制操作(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