海量python字典优化解析,多线程
Optimizing parsing of massive python dictionary, multi-threading
让我们举一个小例子 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 复杂一点。
我更感兴趣的是如何使用具有数百万个键和长值列表的字典来计算可能的价值。
如果您有足够的内存:
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])}
如果您可以将所有内容存储在一个 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倍
让我们举一个小例子 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 复杂一点。
我更感兴趣的是如何使用具有数百万个键和长值列表的字典来计算可能的价值。
如果您有足够的内存:
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])}
如果您可以将所有内容存储在一个 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倍