networkx反向功能的开销?

时间:2015-05-12 20:50:40

标签: python graph reverse networkx

我有以下代码:

import networkx

def reverse_graph(g):
    reversed = networkx.DiGraph()
    for e in g.edges():
        reversed.add_edge(e[1], e[0])
    return reversed


g = networkx.DiGraph()

for i in range(500000):
    g.add_edge(i, i+1)

g2 = g.reverse()
g3 = reverse_graph(g)

根据我的线型分析器,我花费更多时间使用networkx来反转图形(他们的反向花费了大约21秒,我的大约花了7秒)。在这个简单的情况下,开销似乎很高,而且在其他代码中,对于更复杂的对象,它的情况更糟。在networkx我不知道的情况下是否发生了一些事情?这似乎应该是一个相对便宜的功能。

供参考,以下是reverse函数

doc

编辑:我还尝试以相反的方式运行实现(即我的第一个),以确保在创建他们的时候没有缓存发生。我的速度仍然快得多

1 个答案:

答案 0 :(得分:2)

The source code for the reverse method看起来像这样:

def reverse(self, copy=True):
    """Return the reverse of the graph.

    The reverse is a graph with the same nodes and edges
    but with the directions of the edges reversed.

    Parameters
    ----------
    copy : bool optional (default=True)
        If True, return a new DiGraph holding the reversed edges.
        If False, reverse the reverse graph is created using
        the original graph (this changes the original graph).
    """
    if copy:
        H = self.__class__(name="Reverse of (%s)"%self.name)
        H.add_nodes_from(self)
        H.add_edges_from( (v,u,deepcopy(d)) for u,v,d 
                          in self.edges(data=True) )
        H.graph=deepcopy(self.graph)
        H.node=deepcopy(self.node)
    else:
        self.pred,self.succ=self.succ,self.pred
        self.adj=self.succ
        H=self
    return H

因此默认情况下,当copy=True时,不仅边缘节点被反转, 但也可以对任何边缘数据进行深度复制。然后图形属性(保持在 self.graph)被深度复制,然后节点本身被深度复制。 这是reverse_graph没有做的很多复制。

如果您没有对所有内容进行深度检查,则修改g3可能会影响g

如果您不需要深入检查所有内容,(如果可以接受变异g那么

g.reverse(copy=False)

甚至比

更快
g3 = reverse_graph(g)
In [108]: %timeit g.reverse(copy=False)
1000000 loops, best of 3: 359 ns per loop

In [95]: %timeit reverse_graph(g)
1 loops, best of 3: 1.32 s per loop

In [96]: %timeit g.reverse()
1 loops, best of 3: 4.98 s per loop