Skip to main content
 首页 » 编程设计

python之为什么我的电脑运行这个 python 程序时速度变慢并且没有响应

2025年05月04日22zlslch

x=len(str(2**1000000000)) 
print(x) 

我觉得这很有趣,但我的电脑开始卡顿并且没有响应,到底发生了什么?

请您参考如下方法:

在 Python 中,整数世界中的计算通常以任意大小完成。所以这意味着,如果您计算 2**1000000000,它不会使用 32 位整数或 64 位整数来执行此操作,而是使用 long在 Python-2.x 中,或 Python-3.x 中的 int(但 Python-3.x 中的 int)具有任意大小。

2**1000000000 是一个巨大的数字。它需要 1'000'000'000 位,或至少 125'000'000 字节。它还将使用算法计算功率,并且还必须表示中间结果。

在 CPython 中,它需要 133 MB 的内存来存储值。但这还没有结束。现在您想将其转换为字符串。该字符串将占用大约 301'029'995 位数字。每个数字至少占用一个字节。所以这将额外占用 301 MB 的内存,而且计算十进制表示需要大量工作:每次迭代,我们必须执行模 10 检查,而且我们需要将数字除以 10,所以它在数字的位数上(至少)二次方工作。由于位数很大(约 3 亿),因此需要大量的工作。

len(..) 操作不是很昂贵,但是上面的步骤在内存(和 CPU 时间上,尤其是转换为字符串)上都是昂贵的。内存似乎是一个我们可以忽略的因素,但如果我们消耗大量内存,系统可能会变慢,甚至死机。通常,如果系统用完 RAM 内存,它将开始使用交换 内存:它将部分 RAM 内存换出到硬盘驱动器,这非常慢(与 RAM 内存相比)。

上面简略的获取位数的方法肯定不是什么好方法。例如,它也不适用于负数。有一个数学概念叫做对数,如果你取一个数的log10,你得到的位数是减去一个。这里还有一些额外的问题:

  1. 负数的 log10 未定义;和
  2. log10 也不是零。

但我们可以解决这些问题。例如通过构造函数:

from math import log10, floor 
 
def number_of_digits(x): 
    if x == 0: 
        return 1 
    else: 
        return 1 + floor(log10(abs(x))) 

这适用于所有整数值。如果你想计算一个幂的位数,我们甚至可以在一开始就避免计算 2**1000000000:

from math import log10, floor 
 
def number_of_digits_power(x, y): 
    return 1 + floor(y * log10(x)) 

所以位数是:

>>> number_of_digits_power(2, 1000000000) 
301029996 

这在速度和内存方面都很有效。