asyncio:异步程序比同步程序慢

时间:2020-08-14 12:10:34

标签: python asynchronous python-asyncio primes palindrome

我编写的程序遍历了一个范围,并找到素数和回文数。 作为学习异步的一部分,我尝试使用异步来重新构造它。但是结果并不理想。这里的异步代码要比同步代码花费更长的时间。

同步代码

let arr = [
  "haii",
  "keep",
  "these in the same array but",
  "stop here",
  "then continue",
  "until you reach",
  "another",
  "stop here",
  "and finally",
  "stop here",
  "stop here"
];

Array.prototype.split = function() {
  return this.join("UNIQUE_SEPERATOR")
    .split("stop here")
    .map(el => el.split("UNIQUE_SEPERATOR").filter(Boolean))
    .filter(arr => arr.length);
};

console.log(arr.split());

结果:

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 并运行代码 103秒完成。

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

1 个答案:

答案 0 :(得分:4)

您的用例似乎只占用大量CPU,并且不需要IO工作。

python中的异步主要用于在IO操作(http请求,文件写入)运行时继续使用CPU

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

相关问题