首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用多线程加速Python代码

使用多线程加速Python代码

作者头像
会呼吸的Coder
发布2020-02-17 16:56:49
7110
发布2020-02-17 16:56:49
举报

很多时候,我们大部分使用Python编写代码,python因为其简洁,在一些小功能的开发确实快一些,当我们的代码执行远程请求或读取多个文件或对某些数据进行处理。在很多情况下下,我们大家都是利用循环去读取,这种方法要花很长时间才能完成执行。

import requests
from time import time

url_list = [
    "https://via.placeholder.com/400",
    "https://via.placeholder.com/410",
    "https://via.placeholder.com/420",
    "https://via.placeholder.com/430",
    "https://via.placeholder.com/440",
    "https://via.placeholder.com/450",
    "https://via.placeholder.com/460",
    "https://via.placeholder.com/470",
    "https://via.placeholder.com/480",
    "https://via.placeholder.com/490",
    "https://via.placeholder.com/500",
    "https://via.placeholder.com/510",
    "https://via.placeholder.com/520",
    "https://via.placeholder.com/530",
]

def download_file(url):
    html = requests.get(url, stream=True)
    return html.status_code

start = time()

for url in url_list:
    print(download_file(url))

print(f'Time taken: {time() - start}')

输出:

Time taken: 4.128157138824463

这是很明显的案例,这段代码将依次打开每个URL,等待其加载,打印其状态代码,然后再移至下一个URL。如果用上面的写法将十分耗时,这种代码非常适合用于多线程。

利用多线程,您可以以非常低的开销同时执行多个任务。接下来我们去试一下。

我们使用 current.futures 库的ThreadPoolExecutor实现多线程。然后我们写一下多线程代码,并解释原理。

import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from time import time

url_list = [
    "https://via.placeholder.com/400",
    "https://via.placeholder.com/410",
    "https://via.placeholder.com/420",
    "https://via.placeholder.com/430",
    "https://via.placeholder.com/440",
    "https://via.placeholder.com/450",
    "https://via.placeholder.com/460",
    "https://via.placeholder.com/470",
    "https://via.placeholder.com/480",
    "https://via.placeholder.com/490",
    "https://via.placeholder.com/500",
    "https://via.placeholder.com/510",
    "https://via.placeholder.com/520",
    "https://via.placeholder.com/530",
]

def download_file(url):
    html = requests.get(url, stream=True)
    return html.status_code

start = time()

processes = []
with ThreadPoolExecutor(max_workers=10) as executor:
    for url in url_list:
        processes.append(executor.submit(download_file, url))

for task in as_completed(processes):
    print(task.result())


print(f'Time taken: {time() - start}')

输出:

Time taken: 0.4583399295806885

代码处理速度增加了9倍!如果有更多的URL,则性能差异应该更明显。

为什么多线程速度那么快。当我们在调用executor.submit时,我们往线程池添加一个新的任务。

那到底是怎么回事?调用时,executor.submit我们正在向线程池添加新任务。连接其存储起来,之后我们将便利调用任务,并打印结果。

as_completed方法是用来在一个任务完成后,立即从任务列表拿出一个任务去执行。只有已经执行完成或者被取消,任务才会标记为完成状态。我们也可以向其传递一个超时参数,如果任务花费的时间超过该时间段,则即使也会as_completed切换任务。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 初级程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档