Python 为什么从dict.keys()初始化Set要比使用Set.add()快?
代码 结果Python 为什么从dict.keys()初始化Set要比使用Set.add()快?,python,python-3.x,time-complexity,Python,Python 3.x,Time Complexity,代码 结果 total_exc_time = 0 for _ in range(10): start = time.time() set_a = set() dict_a = dict() add = set_a.add for index in range(1000000): dict_a[index] = index add(index) total_exc_time += ((time.time() - sta
total_exc_time = 0
for _ in range(10):
start = time.time()
set_a = set()
dict_a = dict()
add = set_a.add
for index in range(1000000):
dict_a[index] = index
add(index)
total_exc_time += ((time.time() - start) * 1000)
total_exc_time = 0
for _ in range(10):
start = time.time()
dict_a = dict()
for index in range(1000000):
dict_a[index] = index
set_a = set(dict_a.keys())
total_exc_time += ((time.time() - start) * 1000)
第一个代码的时间复杂度不是O(n)吗?后面的代码的时间复杂度不是O(n)的2倍吗。这里的繁重任务是计算密钥散列。在这两种情况下,都会发生两次:添加到dict,然后添加到set。其他程序应该是轻的。您可以使用调试器显示要验证的C调用
除了Carcigenicate提到的函数调用开销之外,内存管理也可能起到一定的作用。如果集合知道长度,当预定义的空间不足时,它可能避免复制数据。函数调用有开销。任何开销乘以一千万都会变得更加引人注目。Idk,如果是这样的话,但这是一种可能性。“第一个代码的时间复杂度是O(n),以后的代码的时间复杂度是O(n)的2倍”-这不是渐进复杂度的工作方式。对不起,我知道它们有相同的O(n),但是,第一个代码看起来比后面的代码计算量少。@bakumpai为什么在你看来是这样的?dict.keys()的原因?dict.keys()不填充列表吗?它的价格是O(n)?@bakumpai不,它不是。即使它这样做了,将其传递到
set
也可能比在循环中使用.add
更快。对于初学者来说,即使它做了同样的事情(不是预先分配整个集合),它仍然会更快,因为它都是在编译代码中完成的,而您的循环是在解释器、字节码级别,这将总是非常慢。dict.keys()是视图。我甚至没有想到重新分配/扩张的潜力。我认为它不能考虑这一点,因为set
的签名指定了一个“iterable”,它没有长度,但它可以执行属性检查或其他任何操作。@Carcigenicate不得不承认我没有验证自己,这是假设的。
332.3066234588623 ms
283.2982540130615 ms