如何在python中优化以下算法的内存和时间使用

如何在python中优化以下算法的内存和时间使用,python,performance,sorting,memory,networkx,Python,Performance,Sorting,Memory,Networkx,我试图在Python中完成以下逻辑操作,但遇到内存和时间问题。因为,我对python非常陌生,所以对于如何以及在何处优化该问题的指导将不胜感激!(我理解以下问题有点抽象) 然后根据这里提到的标准对生成的字典中的列表进行排序 我的问题是: 1) 有没有比使用for循环进行迭代更好的方法 2) 解决上述问题的最佳(最快)方法是什么?我应该考虑使用另一种数据结构而不是字典吗?或者可能是文件操作 3) 因为我需要对这个字典中的列表进行排序,它有10000个键,每个键对应一个10000个值的列表,所以内

我试图在Python中完成以下逻辑操作,但遇到内存和时间问题。因为,我对python非常陌生,所以对于如何以及在何处优化该问题的指导将不胜感激!(我理解以下问题有点抽象)

然后根据这里提到的标准对生成的字典中的列表进行排序

我的问题是:

1) 有没有比使用for循环进行迭代更好的方法

2) 解决上述问题的最佳(最快)方法是什么?我应该考虑使用另一种数据结构而不是字典吗?或者可能是文件操作

3) 因为我需要对这个字典中的列表进行排序,它有10000个键,每个键对应一个10000个值的列表,所以内存需求很快就会变得巨大,我用完了它

3) 是否有办法将排序过程集成到字典本身的计算中,即避免进行单独的循环排序


任何意见都将不胜感激!谢谢

使用返回列表的函数时,请检查返回迭代器的函数。

这将提高内存使用率

在您的例子中,
nx.nodes
返回完整的列表。见:

使用
节点\u iter
,因为它返回迭代器。这应该确保在对for循环中的节点进行迭代时,内存中没有完整的节点列表

见:

一些改进:

import networkx as nx 
    dic_score = {}
    G = nx.watts_strogatz_graph(10000,10,.01) 
    H = nx.watts_strogatz_graph(10000,10,.01)
    for Gnodes in G.nodes_iter() ----------------> changed from G.nodes()
        for Hnodes in H.nodes_iter()  -----------> changed from H.nodes()
           score = SomeOperation on (Gnodes,Hnodes) 
           dic_score.setdefault(Gnodes,[]).append([Hnodes, score, -1 ])
您还可以使用另一个习惯用法,因为现在有两个迭代器:use

1) 您可以使用
itertools
模块中的一个函数来实现此目的。让我提一下,您可以阅读手册或致电:

from itertools import product
help(product)
下面是一个例子:

for item1, item2 in product(list1, list2):
    pass
2) 如果结果太大,无法存储在内存中,请尝试将其保存在某个位置。您可以将其输出到CSV文件中,例如:

with open('result.csv') as outfile:
   writer = csv.writer(outfile, dialect='excel')
   for ...
       writer.write(...)
这将释放你的内存

3) 我认为最好在事后对结果数据进行排序(因为
sort
函数相当快),而不是将问题复杂化,并对数据进行动态排序

您可以使用arroy/矩阵运算(求和、乘积,甚至将函数映射到每个矩阵行)。这些都是如此之快,有时过滤数据的成本比计算所有东西都要高

如果您的应用程序仍然非常慢,请尝试对其进行评测,以准确了解哪些操作速度慢或执行的次数太多:

from cProfile import Profile
p = Profile()

p.runctx('my_function(args)', {'my_function': my_function, 'args': my_data}, {})
p.print_stats()
您将看到以下表格:

      2706 function calls (2004 primitive calls) in 4.504 CPU seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     2    0.006    0.003    0.953    0.477 pobject.py:75(save_objects)
  43/3    0.533    0.012    0.749    0.250 pobject.py:99(evaluate)
...

其他人提到了
itertools.product
。这很好,但在您的例子中,还有另一种可能性:内部循环的生成器表达式和排序的
函数。(当然,代码未经测试。)


内部循环被生成器表达式替换。它也是动态排序的(假设您想在
分数上对每个内部列表进行排序)。不必存储在字典中,您可以轻松地将每个内部列表写入一个文件,这将有助于节省内存。

10^4 x 10^4 nodes=10^8。当然慢了。如果没有您正在尝试执行的操作的信息,运行时和内存使用率很难提高。@nhahtdh:基本上,循环代表提取与每个节点关联的向量。我感兴趣的是两个图中所有可能的向量对的点积,即10000*10000对。因此,每个节点将与10000个这样的点积相关联,然后我想对其进行排序并保存以供进一步处理。正如您正确提到的,计算时间非常长,内存需求也非常大,我希望通过一些文件操作或任何其他建议来优化内存需求。非常感谢您提供的详细答案。让我看看你的反馈并观察结果。NumPy数组也能节省内存。谢谢你的回答。我在这里不确定,因为我正在学习Python,但遇到了一个cPickle模块。在每次内部循环后使用它会对我的原因有所帮助吗?如果内存是你的主要问题,你可以用将结果写入磁盘来代替
dic_score[Gnodes]=…
。我对泡菜知之甚少,无法帮助你,但我认为它会起作用。这真的很有帮助!谢谢你的见解。我正在努力落实你的所有建议。
from cProfile import Profile
p = Profile()

p.runctx('my_function(args)', {'my_function': my_function, 'args': my_data}, {})
p.print_stats()
      2706 function calls (2004 primitive calls) in 4.504 CPU seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     2    0.006    0.003    0.953    0.477 pobject.py:75(save_objects)
  43/3    0.533    0.012    0.749    0.250 pobject.py:99(evaluate)
...
import networkx as nx
from operator import itemgetter 
dic_score = {}
G = nx.watts_strogatz_graph(10000,10,.01) # Generate 2 graphs with 10,000 nodes using Networkx
H = nx.watts_strogatz_graph(10000,10,.01)
for Gnodes in G.nodes():
    dic_score[Gnodes] = sorted([Hnodes, score(Gnodes, Hnodes), -1] for Hnodes in H.nodes(), key=operator.itemgetter(1)) # sort on score