【问题标题】:Fastest way to add/multiply two floating point scalar numbers in python在python中添加/相乘两个浮点标量数的最快方法
【发布时间】:2018-09-18 03:41:09
【问题描述】:

我正在使用 python,显然我的程序中最慢的部分是对浮点变量进行简单的添加。

大约 400,000,000 次加法/乘法运算大约需要 35 秒。

我正在尝试找出我能做这个数学的最快方法。

这就是我的代码结构的样子。 示例(虚拟)代码:

def func(x, y, z):
    loop_count = 30
    a = [0,1,2,3,4,5,6,7,8,9,10,11,12,...35 elements]
    b = [0,11,22,33,44,55,66,77,88,99,1010,1111,1212,...35 elements]
    p = [0,0,0,0,0,0,0,0,0,0,0,0,0,...35 elements]
    for i in range(loop_count - 1):
        c = p[i-1]
        d = a[i] + c * a[i+1]
        e = min(2, a[i]) + c * b[i]
        f = e * x
        g = y + d * c
        .... and so on
        p[i] = d + e + f + s + g5 + f4 + h7 * t5 + y8
    return sum(p)

func() 被调用了大约 200k 次。 loop_count 大约是 30。我有 ~20 次乘法和 ~45 次加法以及 ~10 次使用 min/max

我想知道是否有一种方法可以让我将所有这些声明为 ctypes.c_float 并使用 stdlib 或类似的东西在 C 中进行加法?

注意循环结束时计算的p[i]在下一次循环迭代中用作c。对于第 0 次迭代,它只使用 p[-1],在这种情况下为 0。

我的限制:

  • 我需要使用 python。虽然我理解普通数学在 C/Java/等中会更快。我无法使用它,因为我在 python 中执行的许多其他操作无法在同一程序中的 C 中完成。
  • 我尝试使用 cython 编写此代码,但它导致我需要在其中运行此代码的环境出现一系列问题。所以,再一次 - 不是一个选项。

【问题讨论】:

  • numpy 与并行化无关。你确定你了解你的限制吗?
  • 请注意,您的代码将在for 循环的第一次迭代中生成IndexError,因为p[i-1]i 的值是0
  • @blhsing 它将使用 p 的最后一个索引 - 在第一次迭代中是 0。在第二次迭代中是 p[0] 在最后一行中设置
  • @AbdealiJK 确实。有一个大脑故障时刻。
  • @StephenRauch - 删除它以查看答案,我的意思是这不能修改为向量数学。但也许我对 numpy 功能的理解有限,我看不到一个简单的方法来使用它。

标签: python python-3.x performance math optimization


【解决方案1】:

我认为你应该考虑使用 numpy.你没有提到任何约束。

简单点操作(x.y)的例子

import datetime
import numpy as np

x = range(0,10000000,1)
y = range(0,20000000,2)
for i in range(0, len(x)):
    x[i] = x[i] * 0.00001
    y[i] = y[i] * 0.00001

now =  datetime.datetime.now()
z = 0
for i in range(0, len(x)):
    z = z+x[i]*y[i]
print "handmade dot=", datetime.datetime.now()-now
print z

x = np.arange(0.0, 10000000.0*0.00001, 0.00001)
y = np.arange(0.0, 10000000.0*0.00002, 0.00002)

now =  datetime.datetime.now()
z = np.dot(x,y)
print 'numpy dot =',datetime.datetime.now()-now
print z

输出

handmade dot= 0:00:02.559000
66666656666.7
numpy dot = 0:00:00.019000
66666656666.7

numpy 的速度提高了 100 倍以上。

原因是 numpy 封装了一个 C 库,该库对编译后的代码进行点操作。在完整的 python 中,你有一个潜在的通用对象列表,铸造,......

【讨论】:

  • 虽然我完全同意这一点,但我这里没有点操作。在当前的方法中,我所能做的就是用 np.float 做简单的 + 和 - > 这比用普通的 python 浮点数慢 3 倍 PS:我确实有一个约束 numpy/numba 不能工作,因为我不能矢量化这个数学,但@stephen Raunch 的第一条评论让我恢复了这一点,因为我认为也许我错过了什么
  • 我意识到您没有点运算,但我没有更简单的示例。而且您并没有说一切,因为从您发布的代码来看,我不明白为什么它不能矢量化。发布您认为无法矢量化的代码,然后我们将讨论它。听起来不错?
  • 在上面的例子中,p[i] 在 For 循环的最后一行被计算。 p[i-1] 被用在 For 循环的第一行。并且所有内部计算都没有封闭形式的表达式,因为它有最小值和最大值。在这种情况下,我永远无法计算下一个 for 循环,因为 p[i-1] 需要执行前一个 for 循环。因此 IMO 不可矢量化
猜你喜欢
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 2012-08-29
  • 1970-01-01
  • 2023-03-07
  • 2022-06-26
相关资源
最近更新 更多