为什么当值是对象时迭代字典键会更快?

问题描述 投票:0回答:1

我知道,一般来说,迭代列表比迭代集合或字典键(在某种程度上)更快。确认:

import timeit list_setup = 'my_list = list(range(100))' list_stmt = 'for n in my_list: n**2' print(f'list : {timeit.timeit(setup=list_setup, stmt=list_stmt, number=100000)}') set_setup = 'my_set = set(range(100))' set_stmt = 'for n in my_set: n**2' print(f'set : {timeit.timeit(setup=set_setup, stmt=set_stmt, number=100000)}') dict_setup = 'my_dict = {n: None for n in range(100)}' dict_stmt = 'for n in my_dict.keys(): n**2' print(f'dict : {timeit.timeit(setup=dict_setup, stmt=dict_stmt, number=100000)}')
产生:

list : 5.110044667 set : 5.137189292 dict : 5.179844875000001
但是如果字典的值是对象而不是

None

,则迭代字典键会明显更快:

dict_obj_setup = ''' class MyClass(object): pass my_dict_obj = {n: MyClass() for n in range(100)} ''' dict_obj_stmt = 'for n in my_dict_obj.keys(): n**2' print(f'dict_obj: {timeit.timeit(setup=dict_obj_setup, stmt=dict_obj_stmt, number=100000)}')
dict_obj: 1.7423309159999985

为什么会发生这种情况?如果我有一组整数需要迭代很多很多次,我是否应该创建一个字典,其键是我的整数,其值是任何随机对象?!

顺便说一句,如果我在所有循环中使用

n*n

 而不是 
n**2
,差异就会消失:

list : 0.32518725 set : 0.344315166 dict : 0.3399045409999999 dict_obj: 0.3662140410000001
    
python list loops dictionary set
1个回答
0
投票
首先,

n**2

n*n
更复杂的操作。
因为在这种情况下功率是可变的。

所以 n**x 不完全是这样,但工作方式如下:

x = 5 total = n for _ in range(x): total += total * n
但是

n*n*n*n*n

不那么复杂。

所以这两个过程的区别就是这样的。一个是动态工作的。其中之一是预先确定的。

第二,如果你用大数据来做这件事,你会发现结果会收敛,并且没有显着差异。

my_dict = {n: None for n in range(10000)} my_list = list(range(10000)) %%timeit for n in my_list: n**2 >>1.95 ms ± 6.69 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %%timeit for n in my_dict.keys(): n**2 >>1.96 ms ± 5.18 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
© www.soinside.com 2019 - 2024. All rights reserved.