我有一个 URL 列表,我试图从中获取 JSON 数据。我正在查看包含 10,000 多个项目的列表,因此速度对我来说至关重要。这在串行处理中花费了很长时间,所以我选择使用会话。我以前没有使用过它,但我已经能够生产出足够快的东西了。
ar_list=['https//:www.foo.com',...,'https//:www.foo2.com']
adapter = HTTPAdapter(pool_connections=workers_num, pool_maxsize=workers_num)
data_list = []
with sessions.FuturesSession(max_workers=workers_num) as session:
session.mount('http://', adapter)
session.mount('https://', adapter)
futures = []
for idx, ar_url in enumerate(ar_list):
resp = session.get(ar_url,headers=headers)
futures.append(resp)
end_time = datetime.datetime.now()
time_delta=end_time-start_time
效果很好,在大约 70us 内运行一个查询(有 10,000 个查询)。 不幸的是,我在获取数据时遇到问题。
futures.append(resp)
给了我一个 Future 对象,我需要对其运行 .result().json()
才能真正获取可用的信息。然而,当我添加这些时,我的运行速度非常慢,每个查询大约 0.4 秒(比 70 秒慢得多!)
我尝试快速运行 FutureSession(如上面的代码所示),然后使用以下方法对 future 列表执行操作:
[item.result().json() for item in as_completed(futures)]
list(map(lambda i: func(futures, i), range(0, len(futures))))
data=[]
with concurrent.futures.ThreadPoolExecutor() as e:
fut = [e.submit(func, i) for i in futures]
for idx,r in enumerate(concurrent.futures.as_completed(fut)):
print(str(idx))
data.append(r.result())
现在这个 ThreadPoolExecutor 也运行得很好,执行任务大约需要 70us 左右。 然而,我在
with
的开始和结束处进行测量,并注意到这两个 with
结构之间存在很大的延迟。看起来就像这样:
with sessions.FuturesSession(max_workers=workers_num) as session:
#some fast operations here
"""
A VERY LARGE DELAY (about 60 seconds)
"""
with concurrent.futures.ThreadPoolExecutor() as e:
#some fast operations here
是否对我在需要很长时间才能解决的两个
with
条件之间创建的所有会话进行了一些清理?我可以看到,必须有一种比两个会话进程更好的方法来获取正确格式化的一些 json 数据,但我似乎找不到更快的方法。
经过大量相关研究后,我发现我经历的漫长等待时间是
as_completed
电话。正如@Simon 所说,漫长的等待时间只是我在等待回复。如果我删除 as_completed
,它会变得和以前一样快,但当然响应是垃圾或 None
。
我正在考虑避免将
as_completed
与回调一起使用,以避免需要等待 as_completed
发生在期货上,而只需从完整的列表中获取它们。希望我很快能带着“解决办法”回来