【问题标题】:Need help optimizing this array builder需要帮助优化此阵列构建器
【发布时间】:2020-06-16 10:23:05
【问题描述】:

我当前的代码有两个主要瓶颈,一个我肯定可以改进,但是这个让我卡住了。它占用了我大约 50% 的运行时间,而且只会变得更糟。

它应该怎么做? 它应该从 Walks 中提取一个数组(步行)并将其分成两个新数组 A 和 B。规则看起来有点奇怪,但我相信它们足够简单。 每个walk应该有偶数N个非负整数,并且一对只是2个整数列表的列表,每个列表的长度也是N。 L 是 N/2。

#example pair: [[1,2,5,6,-4,-1],[8,12,-3,7,4,9]]
#example walks:[[1,0,2,5,3,1]] just 1 walk in this example. Could be k many.
#L = 3
newpairs=[]
for walk in walks:
    Anew = [0 for j in range(2*L)]
    Bnew = [0 for j in range(2*L)]
    for r in range(L):
        Anew[r]   = int((pair[0][r]+walk[r])/2)
        Anew[r+L] = int((pair[0][r]-walk[r])/2)
        Bnew[r]   = int((pair[1][r]+walk[r+L])/2)
        Bnew[r+L] = int((pair[1][r]-walk[r+L])/2)
    newpair = [Anew,Bnew]
    newpairs.append(newpair)

#output:[[[1, 1, 3, 0, 1, 1], [6, 7, -1, 1, 4, -2]]]

我意识到这可能是在黑暗中拍摄,但我很乐意回答任何问题以进一步阐明代码的各个方面。如果不优化这部分,我的项目就无法走得更远。它的运行时间增加了 50% 以上,而且在我推动更大的系列时只会变得更糟。

【问题讨论】:

    标签: arrays python-3.x optimization


    【解决方案1】:

    您的算法看起来很简单,并且没有任何明显的性能错误。您可能不会将运行时间减少一个数量级或类似的东西。不过,您可以进行一些较小的优化。

    1) 使用list 乘法符号来初始化AnewBnew lists。替换这个:

    Anew = [0 for j in range(2*L)]
    Bnew = [0 for j in range(2*L)]
    

    用这个:

    Anew = [0]*2*L
    Bnew = [0]*2*L
    

    基准测试:

    >>> timeit.timeit('[0 for x in range(300)]')
    7.822149500000023
    >>> timeit.timeit('[0]*300')
    0.8999562000000196
    

    2) 使用楼层划分。替换

    Anew[r]   = int((pair[0][r]+walk[r])/2)
    

    和类似的行,用这个:

    Anew[r] = (pair[0][r]+walk[r])//2
    

    基准测试:

    >>> timeit.timeit('[int((x+y)/2) for x in range(-5,5) for y in range(-5,5)]')
    23.69675469999993
    >>> timeit.timeit('[(x+y)//2 for x in range(-5,5) for y in range(-5,5)]')
    11.680407500000001
    

    除此之外,您可能还想考虑使用numpy,因为它几乎总是比处理列表/数组的标准库更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-12
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多