我通过HTTP连接到本地服务器(OSRM)以提交路由并返回驱动时间.我注意到I/O比线程慢,因为似乎计算的等待时间小于发送请求和处理JSON输出所花费的时间(我认为当服务器需要一些时间时I/O更好处理你的请求 - >你不希望它被阻止,因为你必须等待,这不是我的情况).线程受全局解释器锁的影响,因此我看来(以及下面的证据)我最快的选择是使用多处理.
多处理的问题是它太快以至于耗尽了我的套接字并且我收到了一个错误(请求每次都发出一个新的连接).我可以(在串行中)使用requests.Sessions()对象来保持连接活动,但是我不能让它并行工作(每个进程都有它自己的会话).
我目前最接近的代码就是这个多处理代码:
conn_pool = HTTPConnectionPool(host='127.0.0.1', port=5005, maxsize=cpu_count())
def ReqOsrm(url_input):
ul, qid = url_input
try:
response = conn_pool.request('GET', ul)
json_geocode = json.loads(response.data.decode('utf-8'))
status = int(json_geocode['status'])
if status == 200:
tot_time_s = json_geocode['route_summary']['total_time']
tot_dist_m = json_geocode['route_summary']['total_distance']
used_from, used_to = json_geocode['via_points']
out = [qid, status, tot_time_s, tot_dist_m, used_from[0], used_from[1], used_to[0], used_to[1]]
return out
else:
print("Done but no route: %d %s" % (qid, req_url))
return [qid, 999, 0, 0, 0, 0, 0, 0]
except Exception as err:
print("%s: %d %s" % …Run Code Online (Sandbox Code Playgroud) python concurrency multithreading asynchronous python-multiprocessing
如果有这样的列表:
shops=['A','B','C','D']
Run Code Online (Sandbox Code Playgroud)
并且想要创建以下新列表(我将每个元素彼此交叉并创建一个字符串,其中第一部分在第二部分之前是字母数字):
['A-B', 'A-C', 'A-D']
['A-B', 'B-C', 'B-D']
['A-C', 'B-C', 'C-D']
['A-D', 'B-D', 'C-D']
Run Code Online (Sandbox Code Playgroud)
我有这样的事情:
for a in shops:
cons = []
for b in shops:
if a!=b:
con = [a,b]
con = sorted(con, key=lambda x: float(x))
cons.append(con[0]+'-'+con[1])
print(cons)
Run Code Online (Sandbox Code Playgroud)
但是,这对于大型列表来说相当慢(例如1000,其中我有1000*999*0.5输出).我一直在寻找一种更有效的方法吗?
我可以使用if-else子句进行排序,例如
for a in shops:
cons = []
for b in shops:
if a<b:
cons.append(a+"-"+b)
elif a>b:
cons.append(b+"-"+a)
print(cons)
Run Code Online (Sandbox Code Playgroud)
哪个,我还没有定时 - 但我认为主要的减速是双循环
我有一个36,742点的输入,这意味着如果我想计算距离矩阵的下三角形(使用vincenty近似),我需要生成36,742*36,741*0.5 = 1,349,974,563距离.
我想保持彼此相距50公里的对组合.我目前的设置如下
shops= [[id,lat,lon]...]
def lower_triangle_mat(points):
for i in range(len(shops)-1):
for j in range(i+1,len(shops)):
yield [shops[i],shops[j]]
def return_stores_cutoff(points,cutoff_km=0):
below_cut = []
counter = 0
for x in lower_triangle_mat(points):
dist_km = vincenty(x[0][1:3],x[1][1:3]).km
counter += 1
if counter % 1000000 == 0:
print("%d out of %d" % (counter,(len(shops)*len(shops)-1*0.5)))
if dist_km <= cutoff_km:
below_cut.append([x[0][0],x[1][0],dist_km])
return below_cut
start = time.clock()
stores = return_stores_cutoff(points=shops,cutoff_km=50)
print(time.clock() - start)
Run Code Online (Sandbox Code Playgroud)
这显然需要数小时和数小时.我想到的一些可能性:
python ×3
asynchronous ×1
concurrency ×1
distance ×1
geohashing ×1
haversine ×1
list ×1
numpy ×1