我正在尝试使用asyncio运行一段代码,并减少整个代码的执行时间。下面是我的代码,大约需要6秒钟才能完全执行
常规函数调用-(方法1)
from time import time, sleep
import asyncio
def find_div(range_, divide_by):
lis_ = []
for i in range(range_):
if i % divide_by == 0:
lis_.append(i)
print("found numbers for range {}, divided by {}".format(range_, divide_by))
return lis_
if __name__ == "__main__":
start = time()
find_div(50800000, 341313)
find_div(10005200, 32110)
find_div(50000340, 31238)
print(time()-start)
以上代码的输出仅是总执行时间,即 6秒。
多线程方法-(方法2) 在这种情况下使用了多线程,但是令人惊讶的是时间增加了
from time import time, sleep
import asyncio
import threading
def find_div(range_, divide_by):
lis_ = []
for i in range(range_):
if i % divide_by == 0:
lis_.append(i)
print("found numbers for range {}, divided by {}".format(range_, divide_by))
return lis_
if __name__ == "__main__":
start = time()
t1 = threading.Thread(target=find_div, args=(50800000, 341313))
t2 = threading.Thread(target=find_div, args=(10005200, 32110))
t3 = threading.Thread(target=find_div, args=(50000340, 31238))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(time()-start)
以上代码的输出为 12秒。
多处理方法-(方法3)
from time import time, sleep
import asyncio
from multiprocessing import Pool
def multi_run_wrapper(args):
return find_div(*args)
def find_div(range_, divide_by):
lis_ = []
for i in range(range_):
if i % divide_by == 0:
lis_.append(i)
print("found numbers for range {}, divided by {}".format(range_, divide_by))
return lis_
if __name__ == "__main__":
start = time()
with Pool(3) as p:
p.map(multi_run_wrapper,[(50800000, 341313),(10005200, 32110),(50000340, 31238)])
print(time()-start)
多处理代码的输出为 3秒,这比普通的函数调用方法要好。
异步方法-(方法4)
from time import time, sleep
import asyncio
async def find_div(range_, divide_by):
lis_ = []
for i in range(range_):
if i % divide_by == 0:
lis_.append(i)
print("found numbers for range {}, divided by {}".format(range_, divide_by))
return lis_
async def task():
tasks = [find_div(50800000, 341313),find_div(10005200, 32110),find_div(50000340, 31238)]
result = await asyncio.gather(*tasks)
print(result)
if __name__ == "__main__":
start = time()
asyncio.run(task())
print(time()-start)
上面的代码还需要大约 6秒,这与通常的执行功能调用(方法1 )相同。
问题-
为什么我的Asyncio方法无法按预期方式工作并减少了总时间?
代码有什么问题?
答案 0 :(得分:3)
您有专用于CPU的代码。 这样的代码无法使用异步加速。
当您的任务正在等待与CPU不相关的任务时,例如,网络请求或从磁盘读取。通常所有语言都是如此。
在python中,基于线程的方法也无济于事,因为这仍然将您限制在一个核心而不是真正的并行执行。这是由于全局解释器锁定(GIL)。在线程之间启动和切换的开销使其比简单版本慢。 在这方面,线程类似于python中的异步,仅当您等待的时间不是主要花费在CPU上,或者您正在调用不受GIL约束的代码时,它才有帮助。 c个扩展名。
使用multiprocessing
实际上使用了多个CPU内核,因此它比普通解决方案要快。