Python:拥有多个变量或将它们的值存储在列表中是否更好?

时间:2017-06-09 15:28:15

标签: performance python-2.7 list variables

我知道这似乎是一个模糊的问题,但我想知道是否(例如在Python中)最好将多个值存储在单独的变量中,或者将它们存储在逻辑组(列表,数组......)中

在我的确切情况下,我应该将Matlab代码翻译成Python 2.7。它是一个基于物理的模型,它消化8个输入变量并创建两个大型列表作为输出。我发现原始模型有大量的变量在路上计算(> 100)。根据经验:如果多次访问一个计算,它将存储在一个新变量中。示例:

x = 3
y = 5
x2 = x**2
z = x2 + exp(y)
zz = (y+x)/x2

x ^ 2使用两次(用于计算z和zz),因此它存储为x2。这真的比让python计算两次x ** 2快吗?另外,如果我将它们存储在列表中会更快吗?像这样:

x = [3, 5]
z = x[0]**2 + exp(x[1])
zz = sum(x)/x[0]**2

列表中变量的组织可能会牺牲代码的可读性,但我很乐意接受它,如果它使我的代码运行得更快。

1 个答案:

答案 0 :(得分:1)

我可以看到将其保留在列表中没有性能优势。相反,将它放在列表中会使它变慢:

>>>  %%timeit
...: x = 3
...: y = 5
...: x2 = x**2
...: z = x2 + exp(y)
...: zz = (y+x)/x2
...: 
337 ns ± 1.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

>>>  %%timeit
...: x = [3, 5]
...: z = x[0]**2 + exp(x[1])
...: zz = sum(x)/x[0]**2
...: 
716 ns ± 4.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

现在部分原因是因为您在列表条件中计算了x**2两次,但即使修复该问题也不会使列表版本更快:

>>>  %%timeit
...: x = [3, 5]
...: x0 = x[0]**2
...: z = x0 + exp(x[1])
...: zz = sum(x)/x0
...: 
502 ns ± 12.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

如果你比较性能,另一个大问题是你定义了int然后将它们转换为浮点数。在MATLAB中,x = 5生成一个浮点数,而在python中它生成一个整数。从一开始就使用花车做所有事情要快得多,只需在数字的末尾添加..0即可。

>>>  %%timeit
...: x = 3.0
...: y = 5.0
...: x2 = x**2.0
...: z = x2 + exp(y)
...: zz = (y+x)/x2
...: 
166 ns ± 1.12 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

如果你使用numpy数组而不是列表,那就更糟了,因为你从一个浮点列表开始然后必须转换数字和列表,然后将它们转换回来,所有这些都是慢:

>>> %%timeit
...: x = np.array([3., 5.])
...: x0 = x[0]**2.
...: z = x0 + np.exp(x[1])
...: zz = x.sum()/x0
...: 
3.22 µs ± 8.96 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

作为一般规则,尽可能避免进行类型转换,并避免在不提供可读性的情况下编制索引。如果你有一堆值,那么转换为numpy很有用。但仅仅两三个就会损害速度和可读性。