如何更快地增加大数?

时间:2016-05-24 04:55:54

标签: python performance python-2.7

我正在尝试在python中乘以大数字。为了我的目的,我试图评估。

2*odd*(4*odd^2 + 7)/3 - 6*odd^2 - 3

现在我的问题归结为如何在python中更快地增加数字。用浮点数做它会更快吗?答案似乎没有。用

作一个更简单的例子
  

N *(N + 1)/ 2

我的想法是以下代码更快

product = 1
if n % 2 == 0:
    product *= n/2
    product *= n
else:
    product *= (n+1)/2
    product *= n
return product

为什么这会更快?那么你就不必将huuge数n*(n+1)除以2。然而,人们确实浪费了计算检查数量模2。也许try exception更快?

所以我的问题归结为。如何在python中计算产品和非常大数的除法?这是我的工作代码。不要求对此代码进行具体的速度改进。但是关于如何处理大数的除法和乘法的更广泛的问题。我的数字范围是10^(10^6) atm。

def spiral_sum_fast(num):
    rem = num % 6
    if rem % 2 == 0:
        raise Exception("The sidelength must be a odd number")
    odd = 1 + num / 2
    odd_squared = 2 * odd**2

    if rem % 3 == 0:
        temp = odd / 3
        temp *= 8 * odd_squared + 14
    else:
        temp = (4 * odd_squared + 7) / 3
        temp *= 2 * odd
    return temp - 3 * odd_squared - 3


if __name__ == '__main__':

    k = 10**(10**6) + 1
    spiral_sum_fast(k)

3 个答案:

答案 0 :(得分:2)

首先,4 * odd ^ 2 + 7总是2 mod 3.所以你不需要检查。

但无论如何,你不想重新安排操作。考虑4 * 5/3对4/3 * 5的整数运算会发生什么。第一个结果是6.而第二个结果是5.如果您按照操作顺序将分区移动到较早的位置,则数字越大,您将获得更多的信息丢失。

另一点:你永远不想做x**2**使用C' pow(),因此它会产生浮点结果。只需使用x * x代替。它会更快,更准确。

至于n*(n+1)/2的示例,n*(n+1)将始终可以被2整除。而您所做的只是将一个大数字向右移位并且您知道该位你输的是0

看起来你一般都担心将小数字除以小数字。但是(如我给出的第一个例子),如果你过早地进行分工,你将失去信息并获得不太准确的答案。计算也不会更快。如果你用大数字来划分大数字,你可能需要这样的技巧,但是如果你用较小的数字来划分大数字(并且你使用整数运算),结果将比你开始时的大数字短几位。 。它不会更快,也不会更准确,以及早期划分"或使用浮点运算。

答案 1 :(得分:1)

一般来说,您应该专门为专业工作提供图书馆。在你的情况下处理大数字和获得最佳速度可能需要这个。看看这个blog处理大数字并在纯Python和使用Python的GNU Multiple Precision Arithmetic Library之间进行速度比较,这样可以大大提高性能。

答案 2 :(得分:1)

你问题的核心似乎是" python中数字运算的速度有多快?"答案取决于你正在使用的是什么类型的号码,以及你正在使用什么类型的机器。

Python中有4种数字: https://docs.python.org/2/library/stdtypes.html#numeric-types-int-float-long-complex

您使用何种机器的问题会影响浮点数学是快还是慢。在大多数情况下,所有数字工作都会因内存的缓慢而黯然失色,但在某些情况下,您设置的数字设置和指令都将适合缓存,而不受内存访问时间的限制。

所以,接下来的问题是,因为" int"通常在python中通常是32位C长,而且是#34; long"是什么比这更大,你的整体真的大到足以穿过4B障碍成长?从它的声音,是的,所以让我们看看Python longobject的实现: https://github.com/python/cpython/blob/master/Objects/longobject.c

所以,它只是一堆邪教。不可否认,它是它们的线性链,所以,这条链有多长?

>>> k = 10**(10**6) + 1
>>> k.bit_length()/32
103810

好的,int链的长度超过每次点击主内存所需的几百个周期,所以你可能会碰到你实际受CPU限制的点......

直到你看到这个数字实际上有多大

>>> k.bit_length()/(8*1024)
405

405KB?缓存有多大? http://www.intel.com/content/www/us/en/processors/core/6th-gen-core-family-mobile-u-y-processor-lines-datasheet-vol-1.html

那么,L1,64B? L2大概是256KB? L3是可能大约4M的那个。即便如此 - 在这个过程中有多少这些405KB号码被保留? python需要运行多少内存?我们正在捣乱缓存吗?这有多贵?

Approximate cost to access various caches and main memory?

这就是我现在正在挖掘这个洞,但迹象表明缓存耗尽缓慢。你正在使用大数字。大不仅仅是一个数学概念,它还会推动记忆的物理现实。剩下的概要是"有多少临时拷贝是python保持不变?"和#34;解释器如何使用剩余的内存?"是有趣的问题,超出了这个答案的范围。