优化解析海量python字典,多线程



让我们举一个小例子python字典,其中的值是整数列表。

example_dict1 = {'key1':[367, 30, 847, 482, 887, 654, 347, 504, 413, 821],
'key2':[754, 915, 622, 149, 279, 192, 312, 203, 742, 846], 
'key3':[586, 521, 470, 476, 693, 426, 746, 733, 528, 565]}

假设我需要解析列表的值,我已经将其实现为以下函数:

def manipulate_values(input_list):
return_values = []
for i in input_list:
new_value = i ** 2 - 13
return_values.append(new_value)
return return_values

现在,我可以很容易地解析这个字典的值如下:

for key, value in example_dict1.items():
example_dict1[key] = manipulate_values(value)

结果如下:

example_dict1 = {'key1': [134676, 887, 717396, 232311, 786756, 427703, 120396, 254003, 170556, 674028], 
'key2': [568503, 837212, 386871, 22188, 77828, 36851, 97331, 41196, 550551, 715703], 
'key3': [343383, 271428, 220887, 226563, 480236, 181463, 556503, 537276, 278771, 319212]}

这对小型词典来说很管用。

我的问题是,我有一本庞大的字典,里面有数百万个关键字和长长的列表。如果我采用上述方法,算法会慢得令人望而却步。

如何优化以上内容?

(1( 多线程——除了传统的threading模块之外,字典中还有更有效的多线程选项可用于多线程this for语句吗?

(2( 更好的数据结构合适吗?

我问这个问题是因为,在这种情况下,我很纠结如何最好地进行。我看不到比字典更好的数据结构,但字典中的for循环(然后是值列表(相当慢。这里可能有一些设计得更快的东西。

编辑:正如你所能想象的,这在某种程度上是一个玩具示例——有问题的函数比x**2-13要复杂一些。

我更感兴趣的是,如何用一本有数百万个键、有长串值的字典来衡量价值。

如果可以将所有内容存储在numpy数组中,处理速度会更快。为了测试可伸缩性,我将每个列表的大小增加了50万倍,以下是我的结果:

from timeit import timeit
import numpy as np
n = 500000
example_dict1 = {'key1':[367, 30, 847, 482, 887, 654, 347, 504, 413, 821]*n,
'key2':[754, 915, 622, 149, 279, 192, 312, 203, 742, 846]*n, 
'key3':[586, 521, 470, 476, 693, 426, 746, 733, 528, 565]*n}
def manipulate_values(input_list):
return_values = []
for i in input_list:
new_value = i ** 2 - 13
return_values.append(new_value)
return return_values

使用您的方法:

for_with_dictionary = timeit("""
for key, value in example_dict1.items():
example_dict1[key] = manipulate_values(value)
""", "from __main__ import example_dict1,manipulate_values ",number=5)
print(for_with_dictionary)
>>> 33.2095841

带numpy:

numpy_broadcasting = timeit("""
array = np.array(list(example_dict1.values()))
array = array ** 2 - 13
""", "from __main__ import example_dict1, np",number=5)
print(numpy_broadcasting)
>>> 5.039885

速度有了显著的提升,至少提升了6倍。

如果您有足够的RAM:

example_dict2 = dict(zip(example_dict1.keys(), np.array(list(example_dict1.values()))**2 -13))
>>> example_dict2
{'key1': array([134676,    887, 717396, 232311, 786756, 427703, 120396, 254003,
170556, 674028]), 'key2': array([568503, 837212, 386871,  22188,  77828,  36851,  97331,  41196,
550551, 715703]), 'key3': array([343383, 271428, 220887, 226563, 480236, 181463, 556503, 537276,
278771, 319212])}

最新更新