【问题标题】:asyncio : asynchronous program is slower than synchronous oneasyncio : 异步程序比同步程序慢
【发布时间】:2020-08-14 12:10:34
【问题描述】:

我编写的程序循环遍历一个范围并找到素数和回文数。 作为学习 asyncio 的一部分,我尝试使用 async 重新构建它。但是结果并不好。这里的异步代码比同步代码花费的时间要长得多。

同步代码

import math
import time


def prime(n):
    limit=int(math.sqrt(n))
    for j in range(2,limit):
        if(n%j==0):
            return 0
    return 1


def pallindrome(n):
    n=str(n)
    m=n[::-1]
    if(m==n):
        return 1
    return  0


a, b, c = 999999999, 9999999, 0
start = time.time()

for i in range(a, b, -1): 
    if(pallindrome(i)):  
        if(prime(i)):
            c+=1
            print(i)
    if(c==20):
        break
print("took --> ", time.time()-start)

结果:

999727999
999686999
999676999
999565999
999454999
999434999
999272999
999212999
999070999
998979899
998939899
998898899
998757899
998666899
998565899
998333899
998282899
998202899
998171899
998121899
took -->  0.6525201797485352

异步代码

import math , time, asyncio

async def is_prime(n):
    limit= int(math.sqrt(n))
    for j in range(2,limit):
        await asyncio.sleep(0)
        if(n%j==0):
            return 0
    return 1

async def is_pallindrome(n):
    await asyncio.sleep(0)
    n=str(n)
    m=n[::-1]
    if(m==n):
        return 1
    return  0

async def waiting(start):
    while True:
        print("processing --> time took {:.2f} --> still running".format(time.time()-start))
        await asyncio.sleep(2)
    
async def main():
    a, b, c = 999999999, 9999999, 0
    start = time.time()
    for i in range(a, b , -1):
        await asyncio.sleep(0)
        if(await is_pallindrome(i)):  
            if(await is_prime(i)):
                c+=1
                print(i)
        if(c==20):
            break
    print(f"Found {c} results in {time.time()-start}s exiting now")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.create_task(waiting(time.time()))
    future = asyncio.ensure_future(main())
    loop.run_until_complete(future)

结果:

999727999
999686999
999676999
999565999
999454999
999434999
999272999
999212999
999070999
998979899
998939899
998898899
998757899
998666899
998565899
998333899
998282899
998202899
998171899
998121899
Found 20 results in 18.48567509651184s exiting now

另一个有趣的事情是传递loop.set_debug(True) 并运行代码需要 103 秒完成。

有人能解释为什么会这样吗?

【问题讨论】:

  • asyncio 不会让事情并行运行。一次仍然只运行一件事,但现在您还引入了事件循环的开销。
  • 您在哪里创建任务以进行并行执行?反正创建一个任务需要时间,为了节省时间,每个任务都需要足够的时间来执行
  • @AlenPaulVarghese 在我的 PI4 同步方式 3.4 秒和异步方式 163.7 秒 ;-)

标签: python asynchronous python-asyncio primes palindrome


【解决方案1】:

您的用例似乎只是 CPU 密集型的,不需要 IO 工作。

python中的async主要用于一直占用CPU,同时IO操作在运行(http请求、文件写入)

我认为您可能对线程感到困惑。 Python 一次只能使用一个 CPU 内核,异步作业由同一个内核排队执行。这意味着在您的示例中,您不会通过使用异步获得任何好处,但可能会增加一些开销,从而减慢您的执行时间。

【讨论】:

  • 请注意,访问本地文件往往足够快,以至于与异步相关的开销通常也不值得
猜你喜欢
  • 2023-04-09
  • 2016-08-20
  • 2022-12-07
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 2015-02-06
  • 2018-06-08
相关资源
最近更新 更多