networkx 反向函数的开销?

Overhead in networkx reverse function?

我有以下代码:

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

编辑: 我还尝试了 运行 另一种实现方式(即首先是我的),以确保在他们创建自己的实现时没有发生缓存。我的速度仍然明显更快

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