python多线程提高代码_[技巧分享] 使用多线程来加速你的 Python 代码

我们会用 Python 编写来执行远程请求或读取多个文件,或者对一些数据进行处理。在很多这样的情况下,我看到程序员使用一个简单的 for loop 来执行。例如:

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。这种代码非常适合多线程。

现代系统可以运行许多线程,这意味着您可以用非常低的开销同时执行多个任务。为什么我们不试着利用它让上面的代码更快地处理这些 URL 呢?

我们将使用 ThreadPoolExecutor 库中的 concurrent.futures 。它简单易用,我们先看一些代码,然后解释它是如何工作的。

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 时,我们正在向线程池中添加一个新任务。我们将该任务存储在进程列表中。稍后我们迭代过程并打印结果。

as_completed方法在完成后立即从进程列表中生成项目(任务)。任务可以进入完成状态的原因有两个。它要么已经完成,要么被取消。我们还可以将timeout参数传递给as_completed,如果一个任务花费的时间超过这个时间段,就会被取消。

您应该更多地探索多线程。对于琐碎的项目,这是加快代码速度的最快方法。如果你想学习,请阅读更多的 官方文档。

祝您有愉快的一天!再见!

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接

我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值