В моем коде есть функция узкого места, которая эффективно сводится к:
import networkx as nx
class my_class:
def __init__(self):
self.graph = nx.complete_graph(50) # placeholder for large nx graph
self.my_dict = {}
# triggered by event automatically, cannot change trigger
def slow_function(self, event):
source = event.source
dest = event.dest
# how to speed up this function?
def bottleneck_function():
reasonably_fast_obj = reasonably_fast('myfoo')
self.path_calulator(source, dest, reasonably_fast_obj)
def path_calulator(self, source, dest, weight):
return nx.shortest_simple_paths(self.graph, source, dest, weight)
class reasonably_fast:
def __init__(self, foo):
self.foo = foo
Основной причиной является метод networkx, который занимает значительное время для большого графика.
Функция slow_farget запускается таким образом, что она может быть вызвана снова до завершения предыдущего вызова (из-за задержки). Как правильно ускорить задачу?
Можно ли сделать это быстрее, используя несколько потоков?
Примечание : я могу использовать только Python 2.7 из-за некоторых ограничений
Редактировать
Вот что у меня есть:
import networkx as nx
from multiprocessing import Pool as ThreadPool
from itertools import islice
import random
G = nx.barabasi_albert_graph(10, 5)
G.number_of_edges() # prints 25
def nx_function():
src, dst = random.sample(range(0,9), 2)
return list(islice(nx.shortest_simple_paths(G, source=src, target=dst), 5))
%timeit nx_function
дает 10000000 циклов, лучшее из 3: 22,1 нс на цикл
def simple():
for i in range(10):
nx_function()
%timeit simple
дает 100 циклов, лучшее из 3: 1,94 мс на цикл
def parallelized():
pool = ThreadPool(4)
for i in range(10):
pool.apply_async(func=nx_function)
pool.close()
pool.join()
%timeit paralelized
дает 10 циклов, лучшее из 3: 196 мс на цикл
Кажется, что издержки многопроцессорной обработки делают это бесполезным.
Есть ли другой способ ускорить этот код?