多次使用 min() 还是将其存储在变量中对性能更好?
Is it better for performance to use min() mutliple times or to store it in a variable?
我有一个小的 python 代码,它在同一个未更改的列表上多次使用 min(list)
,这让我想知道我是否使用像 min()
、len()
, 等等...多次在未更改的列表上将这些结果存储在变量中对我来说更好吗,它会影响内存使用/性能吗?
如果非要我猜的话,我会说,如果像 min()
这样的函数被多次调用,将它存储在变量中对性能会更好,但我不确定这一点,因为我真的不知道 python 是如何获取值的,或者 python 是否会在列表未更改的情况下自动将此值存储在某个地方。
如果你只使用它1-5次,那真的没关系。但是,如果您打算再调用它,而且真的更少调用它,最好将它保存为一个变量。这样做几乎不需要记忆,而且只需很少的时间就可以将其从记忆中提取出来。
像 min 或 max 这样的函数肯定每次都要遍历数组(给它们 O(n) 的复杂度)。所以是的,特别是如果你的数组更大,最好将它存储在一个变量中而不是再次执行计算。
More details about performance in another question
速度
存储结果并重新使用它几乎总是比多次重新调用函数更便宜。
Python 不缓存(存储并稍后记住)min()
、len()
等函数的结果
这里是一个快速的速度测试:
timeit.timeit("c = min(x) + min(x)", "x = [1, 2, 3]")
0.24990593400000005
timeit.timeit("a = min(x); b = a + a", "x = [1, 2, 3]")
0.1296667110000005
第二个几乎快两倍,因为存储变量比重新调用 min
函数要便宜得多。
内存使用
如果结果是单个数字,如 min()
或 len()
,则内存使用可以忽略不计。
如果结果很重要(例如很大的 table 值),那么您可以在完成后使用 del
将其删除
large_object = expensive_function()
do_something(large_object)
do_something_else(large_object)
del large_object
此外,当大对象超出范围时(例如,当函数 returns 时)或定期进行垃圾收集时,它们将自动从内存中删除。因此,del
仅在某些情况下才有必要,例如处理对对象的循环引用时。
min()
与许多其他操作相比非常快,例如 I/O。因此,对于短列表和只有少数重复调用的效率改进可能很小。但是,如果缓存 min()
的结果,则可以节省一些时间。请参阅下面的代码,了解您实际可以节省的时间示例。如您所见,您需要多次迭代包含 min()
调用的循环才能节省大量时间。
import timeit
lst = range(2)
def test_min():
x = [min(lst) for i in range(10)]
def test_cached_min():
min_lst = min(lst)
x = [min_lst for i in range(10)]
print(timeit.timeit("test_min()", globals = locals(), number = 1000))
print(timeit.timeit("test_cached_min()", globals = locals(), number = 1000))
# lst = range(2):
# 0.0027015960000000006
# 0.0010772920000000005
# lst = range(2000):
# 0.5262554810000001
# 0.05257684900000004
Python 列表操作的时间复杂度
table 表明:
- 函数 len(获取长度)的复杂度为 O(1)(非常快,所以已经存储)
- 函数 min(获得最小值)是 O(n)(取决于列表的大小,因此每次计算)。
这意味着:
- len不需要存储以供重用
- min 应存储以供重用(尤其是对于大型列表)
我有一个小的 python 代码,它在同一个未更改的列表上多次使用 min(list)
,这让我想知道我是否使用像 min()
、len()
, 等等...多次在未更改的列表上将这些结果存储在变量中对我来说更好吗,它会影响内存使用/性能吗?
如果非要我猜的话,我会说,如果像 min()
这样的函数被多次调用,将它存储在变量中对性能会更好,但我不确定这一点,因为我真的不知道 python 是如何获取值的,或者 python 是否会在列表未更改的情况下自动将此值存储在某个地方。
如果你只使用它1-5次,那真的没关系。但是,如果您打算再调用它,而且真的更少调用它,最好将它保存为一个变量。这样做几乎不需要记忆,而且只需很少的时间就可以将其从记忆中提取出来。
像 min 或 max 这样的函数肯定每次都要遍历数组(给它们 O(n) 的复杂度)。所以是的,特别是如果你的数组更大,最好将它存储在一个变量中而不是再次执行计算。
More details about performance in another question
速度
存储结果并重新使用它几乎总是比多次重新调用函数更便宜。
Python 不缓存(存储并稍后记住)min()
、len()
等函数的结果
这里是一个快速的速度测试:
timeit.timeit("c = min(x) + min(x)", "x = [1, 2, 3]")
0.24990593400000005
timeit.timeit("a = min(x); b = a + a", "x = [1, 2, 3]")
0.1296667110000005
第二个几乎快两倍,因为存储变量比重新调用 min
函数要便宜得多。
内存使用
如果结果是单个数字,如 min()
或 len()
,则内存使用可以忽略不计。
如果结果很重要(例如很大的 table 值),那么您可以在完成后使用 del
large_object = expensive_function()
do_something(large_object)
do_something_else(large_object)
del large_object
此外,当大对象超出范围时(例如,当函数 returns 时)或定期进行垃圾收集时,它们将自动从内存中删除。因此,del
仅在某些情况下才有必要,例如处理对对象的循环引用时。
min()
与许多其他操作相比非常快,例如 I/O。因此,对于短列表和只有少数重复调用的效率改进可能很小。但是,如果缓存 min()
的结果,则可以节省一些时间。请参阅下面的代码,了解您实际可以节省的时间示例。如您所见,您需要多次迭代包含 min()
调用的循环才能节省大量时间。
import timeit
lst = range(2)
def test_min():
x = [min(lst) for i in range(10)]
def test_cached_min():
min_lst = min(lst)
x = [min_lst for i in range(10)]
print(timeit.timeit("test_min()", globals = locals(), number = 1000))
print(timeit.timeit("test_cached_min()", globals = locals(), number = 1000))
# lst = range(2):
# 0.0027015960000000006
# 0.0010772920000000005
# lst = range(2000):
# 0.5262554810000001
# 0.05257684900000004
Python 列表操作的时间复杂度
table 表明:
- 函数 len(获取长度)的复杂度为 O(1)(非常快,所以已经存储)
- 函数 min(获得最小值)是 O(n)(取决于列表的大小,因此每次计算)。
这意味着:
- len不需要存储以供重用
- min 应存储以供重用(尤其是对于大型列表)