問(wèn)題背景:這兩天用python做大數(shù)據(jù)處理痢缎,抽取每個(gè)文本單詞币呵,進(jìn)行統(tǒng)計(jì)排序悉尾。數(shù)據(jù)大概有2000萬(wàn)個(gè)突那,利用python多進(jìn)程處理。數(shù)據(jù)同步用的python多進(jìn)程通信中比較常使用的Manager Dict构眯。
原始代碼是這樣寫(xiě)的.
def process_file_path_list(self, path_list, total_tf_map):
? ? ?for path_ in path_list:
? ? ?tf_dict = self.process_file(path_) # extract word in file
? ? ?for (key, value) in tf_dict.items():
# update dict
? ? if key in total_tf_map.keys():
? ? ? ? total_tf_map[key] += value?
? ? else:
? ? ? ? total_tf_map[key] = value
上面這個(gè)代碼跑了一整天才把數(shù)據(jù)跑完愕难,非常耗時(shí),但是抽取word的代碼并不是性能瓶頸所在啊惫霸,另外按理說(shuō)使用字典方式進(jìn)行數(shù)據(jù)存取也不會(huì)太慢啊猫缭,但是這貨就是跑了一整天。壹店。猜丹。實(shí)在受不了了,分析了下原因硅卢,原來(lái)是這句代碼導(dǎo)致的射窒。
if key in total_tf_map.keys():
用過(guò)python的朋友應(yīng)該挺熟悉,判斷一個(gè)key在不在字典里将塑,這個(gè)方法也挺好用的脉顿。但是為啥性能這么低,按理說(shuō)python的字典內(nèi)部實(shí)現(xiàn)上是用哈希表点寥,性能應(yīng)該挺好的啊艾疟。琢磨了半天才發(fā)現(xiàn)這里有個(gè)坑,dict.keys()這個(gè)函數(shù)返回的是一個(gè)列表啊敢辩,是一個(gè)列表蔽莱。。戚长。處理這么大的數(shù)據(jù)盗冷,返回出來(lái)的列表至少也得有幾十萬(wàn)個(gè)數(shù)據(jù),在這些數(shù)據(jù)里找key那豈不不是費(fèi)老大勁了历葛≌坑啊嘀略。。乓诽。
后來(lái)代碼改成:
def process_file_path_list(self, path_list, total_tf_map):
? ? ?for path_ in path_list:
? ? tf_dict = self.process_file(path_)
? ? for (key, value) in tf_dict.items():
# update total_tf_dict_
? ? ?if total_tf_map.get(key) != None:
? ? ? ? ?total_tf_map[key] += value
? ? else:
? ? ? ? total_tf_map[key] = value
利用dict的get方法帜羊,這個(gè)方法是直接利用python哈希表進(jìn)行查找,速度由原來(lái)的一天提高到只要半個(gè)小時(shí)鸠天。讼育。。