我有一个字典列表,我使用每个字典在图表上做一些处理。此处理在一个不返回任何内容的函数内完成。
没有I / O操作也没有网络,它只是计算;基本上,每个字典代表图中的路径,我需要更新该路径的边缘权重。 目前我并不关心图表的存储数据一致性,我只想提高处理时间。
我先是连续,处理for循环中的每个项目:
//use the settings to configure the parser if required.
TsvParserSettings settings = new TsvParserSettings();
TsvParser parser = new TsvParser(settings);
List<String[]> allRows = parser.parseAll(new File("./data/items/books.tsv"), "UTF-8");
然后我决定试一试并将其并行化,因为dicts列表可能包含多达数万个字典,我可以在具有相当多CPU的计算机上访问。我的第一次尝试是使用线程模块,但结果比串行版本差得多。 在SO和网络中阅读这里的一些问题,我发现有几个建议使用multiprocessing.Pool类而不是GIL导致的线程。 结果优于仅仅使用线程,但串行版本仍然优于它(在四核PC上大约需要一半的时间!)。以下是我为此并行版本尝试过的内容:
def processDict(dic, graph):
# Modify graph according to the data stored in the dictionary
# Returns nothing
def updatePheromone(listOfDicts):
# Graph is accesible within this function's scope
for dic in listOfDicts:
processDict(dic, graph)
我觉得我在这种方法中犯了错误。可怜的表现是否与传递给地图的功能是&#34; void&#34; 类型的功能有关?我应该使用其他一些图书馆或班级吗?
编辑:我在Linux上运行它。答案 0 :(得分:4)
我觉得我在这种方法中犯了错误。
可能的原因是传递了太多数据。
进程不共享内存,因此您传入的任何数据都必须在一侧进行序列化,通过通道(如原始套接字)传输,并在另一侧进行反序列化。如果所花费的时间超过并行处理所节省的时间,则结果是净损失。
处理此问题的一种方法是在创建池之前将内存中的图形作为全局变量(使数据可以通过写时复制共享)。然后只需将索引(单个数字)传递给流程,然后让它在图表的各个部分工作。