python - API 上的 For 循环
问题描述
我在一个名为“ y ”的列表中有一个大约 28K 数字的列表,我正在 API 上运行一个 for 循环来发送消息,但这需要很多时间(准确地说是每次调用 1.2797 秒)
代码:
import timeit
start = timeit.default_timer()
for i in y:
data = {'From': 'XXXX', 'To': str(i),
'Body': "ABC ABC" }
requests.post('https://xxxx:xx@api.xxx.com/v1/Accounts/xxx/Sms/send',data=data)
stop = timeit.default_timer()
print('Time: ', stop - start)
我怎样才能减少这个时间?
解决方案
Asyncio 或 Multithreading 是优化代码的两种可能的解决方案,并且两者基本上都在幕后做同样的事情:
螺纹
import timeit
import threading
import time
y = list(range(50))
def post_data(server, data, sleep_time=1.5):
time.sleep(sleep_time)
# request.post(server, data=data)
start = timeit.default_timer()
server = 'https://xxxx:xx@api.xxx.com/v1/Accounts/xxx/Sms/send'
threads = []
for i in y:
# if you don't need to wait for your threads don't hold them in memory after they are done and instead do
# threading.Thread(target, args).start()
# instead. Especially important if you want to send a large number of messages
threads.append(threading.Thread(target=post_data,
args=(server, {'From': 'XXXX', 'To': str(i), 'Body': "ABC ABC"}))
threads[-1].start()
for thread in threads:
# optional if you want to wait for completion of the concurrent posts
thread.join()
stop = timeit.default_timer()
print('Time: ', stop - start)
异步
import timeit
import asyncio
from concurrent.futures import ThreadPoolExecutor
y = list(range(50)
_executor = ThreadPoolExecutor(len(y))
loop = asyncio.get_event_loop()
def post_data(server, data, sleep_time=1.5):
time.sleep(sleep_time)
# request.post(server, data=data)
async def post_data_async(server, data):
return await loop.run_in_executor(_executor, lambda: post_data(server, data))
async def run(y, server):
return await asyncio.gather(*[post_data_async(server, {'From': 'XXXX', 'To': str(i), 'Body': "ABC ABC"})
for i in y])
start = timeit.default_timer()
server = 'https://xxxx:xx@api.xxx.com/v1/Accounts/xxx/Sms/send'
loop.run_until_complete(run(y, server))
stop = timeit.default_timer()
print('Time: ', stop - start)
当使用不支持异步但会从并发中受益的 API 时,比如您的用例,我倾向于使用线程,因为它更容易阅读恕我直言。如果您的 API/库确实支持 asyncio,那就去吧!这很棒!
在我的机器上,有 50 个元素的列表,异步解决方案的运行时间为 1.515 秒,而线程解决方案在执行 50 个实例时需要大约 1.509 秒time.sleep(1.5)
。
推荐阅读
- python - Python,pip:安装过程中避免使用 gcc
- ios - 当用户想要在从一个选项卡导航到另一个选项卡时不自动刷新 webViewController 时如何刷新它
- java - 应用程序跳帧
- json - 节点函数不返回 JSON 对象
- php - paypal rest api 多重计费协议
- robotframework - 如何从 cmd unittest 更改键形式字典
- java - 我可以访问数据库,但是在使用 java 将文档插入 mongodb 集合时遇到了一些异常
- scala - 如何将列表列表转换为 Scala 中的 DataFrame?
- ruby-on-rails - 如何在 Rails Webpacker 中添加多个 source_path
- python-3.x - 使用一列中的重复值删除熊猫数据框中的整行