【发布时间】:2020-06-15 22:42:30
【问题描述】:
假设我要生成以下递归序列:
与以下封闭形式的序列相同:
但目标是编写一个函数来生成具有递归定义的序列。所以,以下是我的功能:
def gen_seq(n):
'''
n is the number of terms to generate in the sequence
'''
lis = [1] # starting number of the sequence
for i in range(1,n):
lis.append(lis[-1] + 2*(i+1) - 1)
return lis
我们可以看一下序列的前 10 个词:
gen_seq(10)
>>> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
如果我们查看生成序列中前 1000 万个数字所花费的时间:
import time
t = time.time()
foo = gen_seq(10000000)
print('Time taken: {}s'.format(time.time()-t))
>>> Time taken: 6.146637201309204s
需要 6.1 秒。对于 1 亿个数字,所用时间为 1 分钟。序列越复杂,所花费的时间就会越多。
如何优化此功能以使其更快?
【问题讨论】:
-
你可能想看看像 numba 这样的编译器:numba.pydata.org
-
从 1000 万到 10000 万个元素的泛化通常是不正确的,因为它取决于底层列表调整大小的长度,因此需要分配新内存和复制旧元素。如果您事先知道大小,最好先创建列表(例如
[None] * n),然后再填写(这也适用于递归问题)。当然,您也可以使用生成器。 -
你真的需要一次存储所有 100,000,000 个数字吗?
-
@chepner 实际上我正在生成 1000 万个具有 2 个不同起始数字的序列,然后分析这两个序列之间的差异。所以,我并没有过多考虑记忆和所有这些。无论如何,即使我不将单个序列存储在内存中,我也至少需要将序列的差异存储在内存中。
-
@SergeBallesta 列表理解在 C 中类似地循环,因此仅就循环而言,与 numpy 没有区别。加速来自 Python 中结果列表中的每个数字都由一个对象表示,因此会带来一些开销,而 numpy 使用它自己的数据类型 (
np.int64) 并只存储数字。比较np.arange(100_000, dtype=object),加速就没有了。
标签: python python-3.x performance loops optimization