Update:
I realized that GraphView has an efilt as well, so I've added an edge_property to keep track of which edges were part of the original graph.
Oddly enough, this didn't improve things as it seems like the bottle neck wasn't in edge removal (which is supposed to be O(1) with set_fast_edge_removal(True)), but rather with constructing the edge object using g.edge(src, tgt).
I tried using gv.add_edge() in a loop and saving the result (instead of using add_edge_list). That made setting the edge properties at the end fast, but adding the edges one by one ends up being as slow as reconstructing the edge object.
What seems to have worked is to instead add another edge property map to keep track of the new edges, and set that with add_edge_list, then copy it over to the property map that gets used to the filtering.
With all of this in place this has pushed the graph "copying" down to 5% of the routine, which seems reasonable for now. If someone has other suggestions I'm all ears :)
Thanks again,
-z
Here's the MWE using efilt implementation:
```
import graph_tool.all as gt
import numpy as np
g = gt.Graph(directed=False)
g.add_vertex(10)
original_edges = [[0, 1], [0, 4]]
g.add_edge_list(original_edges)
g.edge_properties['orig'] = g.new_edge_property('bool', val=True)
g.edge_properties['oorig'] = g.new_edge_property('bool', val=True)
g.set_fast_edge_removal(True)
n_orig = g.num_vertices()
def foo(g, m):
n_act = g.num_vertices()
n_extra = n_act - (n_orig+m)
if n_extra < 0:
print(f'adding {-n_extra} vertices ...')
g.add_vertex(-n_extra)
n_extra = 0
n_act = g.num_vertices()
filt = np.ones(n_act)
if n_extra > 0:
filt[(-n_extra):] = 0
gv = gt.GraphView(g, vfilt=filt, efilt=g.edge_properties['orig'])
#print(f'filt = {filt}')
new_vtx_ids = np.arange(n, n+m)
print(f'indices of new vertices = {new_vtx_ids}')
#Check that all edges are expected
for e in list(gv.edges()):
if [e.source(), e.target()] not in original_edges:
raise Exception(f'{e.source()} -> {e.target()} was not in original graph')
#Add a bunch of random edges connecting to new candidates
edge_list = []
for s, t in zip(np.random.choice(range(n_orig), m),
np.random.choice(new_vtx_ids, m)):
edge_list.append([s,t,False])
#Can't set this directly to 'orig' since we are filtering on it, and if it's false
#the edge won't be added to this view!
gv.add_edge_list(edge_list, eprops = [gv.edge_properties['oorig']])
print('Current edges:')
for e in list(gv.edges()):
print(f'{e.source()} -> {e.target()}')
#computation on new graph goes here ...
pass
g.edge_properties['orig'] = g.edge_properties['oorig']
foo(g, 1)
foo(g, 4)
foo(g, 3)
foo(g, 5)
foo(g, 3)
foo(g, 4)
```