【问题标题】:Code optimization help needed, as it is getting stuck in serial operation需要代码优化帮助,因为它卡在串行操作中
【发布时间】:2014-07-04 09:02:55
【问题描述】:

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

【问题讨论】:

    标签: python loops optimization


    【解决方案1】:

    优化函数增长的一种方法: “math.tan”:python 解释器搜索这个全局两次,还必须访问 math 和 tan。 你可以写一个本地 Tan 并将其设置为 math.tan。

    类似于 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[:])
    

    【讨论】:

    • 感谢本尼迪克特!会试试这个,让你知道我怎么走。谢谢!
    【解决方案2】:

    您在每次迭代时重新复制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 也是如此。

    【讨论】:

    • 谢谢塞巴斯蒂安!会试试这个,让你知道我怎么走。谢谢!
    【解决方案3】:

    另一个小的改进是使用 xrange 代替 range。在这里你可以阅读更多: https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Use_xrange_instead_of_range

    【讨论】:

    • 谢谢!也会试试这个,让你知道我是怎么走的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    相关资源
    最近更新 更多