通常为了节省时间,我想在我的本地函数中使用n = len(s)。 我很好奇哪一个调用更快,或者它们是相同的吗?
while i < len(s):
# do something
vs
while i < n:
# do something
这两种方法差异不大,但使用len(s)时需要先获取s,然后调用s.length,这是O(1) + O(1)。而使用n,则为O(1)。我假设如此。
通常为了节省时间,我想在我的本地函数中使用n = len(s)。 我很好奇哪一个调用更快,或者它们是相同的吗?
while i < len(s):
# do something
vs
while i < n:
# do something
这两种方法差异不大,但使用len(s)时需要先获取s,然后调用s.length,这是O(1) + O(1)。而使用n,则为O(1)。我假设如此。
IT必须更快。
n
,您只需查看一次变量(字典)。len(s)
,您需要查看两次(len
也是一个我们要查找的函数)。然后调用该函数。话虽如此,如果使用while i < n:
,大多数情况下您可以通过经典的for i in range(len(s)):
循环来实现,因为上限不会更改,并且仅在range
的开始处被评估一次(这可能会让您想到:我为什么不直接迭代元素或使用enumerate
?)
while i < len(s)
允许将索引与可变列表进行比较。这就是重点所在。如果您固定了边界,则变得不太吸引人。
在for
循环中,使用continue
轻松跳过增量(像忘记递增i
并最终出现无限while
循环一样容易)
你说得对,这里有一些基准测试:
s = np.random.rand(100)
n = 100
%%timeit
50 < len(s)
86.3 ns ± 2.4 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
对比:
%%timeit
50 < n
36.8 ns ± 1.15 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
但是,想象60ns的差异会影响速度还是很难的,除非你要多次调用len(s)
。
O(1) + O(1)
仍然是O(1)
。在考虑缓存返回值之前,应该对代码进行性能分析,以查看重复调用len(s)
是否会产生任何显着的开销。请注意,如果循环中s
的值发生更改,则这样做是 不正确 的。 - chepners
在循环中不会改变。任何运行时优化都将使这两个表达式等效。然而,显而易见的(?)答案是你正在询问错误的实体:使用timeit
分别计时,看看在你的应用程序中哪一个更快。 - Prune