当前位置: 首页 > 知识库问答 >
问题:

API上的For循环

艾璞瑜
2023-03-14

我在一个名为“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)   

我怎样才能减少做这件事的时间?

共有1个答案

潘学民
2023-03-14

Asyncio或多线程是优化代码的两种可能的解决方案,它们基本上都是这样做的:

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时,就像您的用例一样,我倾向于使用线程,因为它更容易阅读IMHO。如果你的API/库确实支持asyncio,那就去吧!这是伟大的!

在我的机器上,当执行50个time.sleep(1.5)实例时,异步解决方案的运行时间为1.515秒,而线程解决方案需要大约1.509秒。

 类似资料:
  • 我正在访问和API从巴西获得具体的公共预算。它需要定义年、月和页。我成功地使用for循环来获取我想要的2020年的信息,通过月{j}和页(str+1)进行循环。 我如何并行化以下内容(如果我可以将其转换为def函数并使用map就更好了)?

  • 我正在编写一个计算e^x值的方法。我在python中实现它的方式如下。 这将很好地返回e^x的值。但是,当我尝试在c#中实现相同的方法时,它没有输出与python中相同的值。以下是c#中的实现。 起初,这段代码的输出是一个无穷大符号。为了解决这个问题,我只是减少了循环运行的次数。在c#中,循环只运行10次,代码的输出非常接近于python中循环运行100次的输出。我的问题是,在不同的编程语言中,两

  • 我试图在for循环中获得for循环,因此输出如下: 我希望输出显示一个正方形 我不知道它为什么不这样做。下面是我的代码:

  • for循环是一种重复控制结构,允许您有效地编写需要执行特定次数的循环。 语法 (Syntax) Perl编程语言中for循环的语法是 - for ( init; condition; increment ) { statement(s); } 这是for循环中的控制流 - init步骤首先执行,只执行一次。 此步骤允许您声明和初始化任何循环控制变量。 只要出现分号,就不需要在此处输入声明。

  • ' for '循环是最紧凑的循环形式。 它包括以下三个重要部分 - loop initialization ,我们将计数器初始化为起始值。 初始化语句在循环开始之前执行。 test statement将测试给定条件是否为真。 如果条件为真,则执行循环内给出的代码,否则控件将退出循环。 iteration statement ,您可以在其中增加或减少计数器。 您可以将所有三个部分放在一行中以分号分隔

  • 问题 你想通过一个 for 循环来迭代数组、对象或范围。 解决方案 # for(i = 1; i<= 10; i++) x for x in [1..10] # => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] # To count by 2 # for(i=1; i<= 10; i=i+2) x for x in [1..10] by 2 # => [ 1, 3, 5,