为什么python语句“if somethine is None”比“if nothing”工作得快得多?
我在写斐波那契函数时遇到了这个问题。为了更快,我使用了一个名为cache的字典来存储已经计算过的数字。所以我写了为什么python语句“if somethine is None”比“if nothing”工作得快得多?,python,performance,python-3.x,Python,Performance,Python 3.x,我在写斐波那契函数时遇到了这个问题。为了更快,我使用了一个名为cache的字典来存储已经计算过的数字。所以我写了 def fib(n, cache=None): if not cache: cache = {} if n in cache: return cache[n] if n==0 or n==1: return 1 else: cache[n] = fib(n-1, cache) + fib(
def fib(n, cache=None):
if not cache:
cache = {}
if n in cache:
return cache[n]
if n==0 or n==1:
return 1
else:
cache[n] = fib(n-1, cache) + fib(n-2, cache)
return cache[n]
def fib_run(n):
start = time.time()
fib(n)
end = time.time()
print("fib_run cost: {}".format(end-start))
我调用fib_-run(30)
,输出是fib_-run-cost:0.8419640064239502
,它和没有缓存的函数一样慢。
但是当我在函数fib2
中将if not cache:
更改为if cache is None:
时,它的工作速度要快得多
def fib2(n, cache=None):
if cache is None:
cache = {}
if n in cache:
return cache[n]
if n==0 or n==1:
return 1
else:
cache[n] = fib2(n-1, cache) + fib2(n-2, cache)
return cache[n]
def fib2_run(n):
start = time.time()
fib2(n)
end = time.time()
print("fib_run cost: {}".format(end-start))
>>> fib2_run(30)
fib2_run cost: 2.6226043701171875e-05
我想知道为什么这两种方法之间有如此大的差异(我认为它们在早期是一样的)。谢谢。这里的问题不是
无缓存
与无缓存
的性能,而是如果缓存无
仅在第一次调用fib2
时才是真的
而如果没有缓存
则是真的
即使缓存=={}
对于fib
“空”集合的计算结果为False
,因此not
空集合将为True
:
>>> not {}
True
因此,即使在缓存
已经等于{}
的情况下,您也在做额外的工作(将缓存分配给{}
)
一般来说,这些操作在性能上非常相似,一个是简单的身份检查,而另一个是基于值的布尔值(对于字典来说,如果我没有弄错的话,它是基于
\uu len\uuuu
的结果)。在第一种情况下,缓存总是空的!难怪您在没有缓存的情况下获得与函数相同的计时。你所需要的只是一张照片,看看会发生什么
if not cache:
#if cache is None:
print(n, "No cache!")
cache = {}
如上所述,空集合的计算结果为false。在递归调用中,如果not cache
始终为true,则创建一个新的dict,并将其发送到下面的级别,该级别再次计算为false,依此类推。缓存中从来没有一个条目
(如上所述,即使在缓存已经等于{}的情况下,也要做额外的工作,这是一次操作。对于更大的n,不应该花费任何费用)
缓存是无的
是身份检查<代码>非缓存是字典的空性检查。这是引擎盖下的两种不同操作。你的意思是空位检查要花费更多的时间?你能告诉我为什么吗?