python gpu加速库比matlab快吗_python – 为什么asyncio库比这个I / O绑定操作的线程慢?...

本文探讨了Python的asyncio库在处理I/O密集型任务时相对于线程池的性能表现。实验结果显示,由于asyncio版本的并行度限制,导致其在特定场景下速度较慢。通过调整asyncio的线程池大小和使用异步队列,可以使其性能接近线程池版本。在某些情况下,两者性能相当。
摘要由CSDN通过智能技术生成

首先,我无法重现与我在Linux机器上看到的性能差异几乎一样大的性能差异.对于线程版本,我一直看到大约20-25秒,对于asyncio版本在24-34秒之间.

现在为什么asyncio慢了?有一些事情有助于此.首先,asyncio版本必须顺序打印,但线程版本不会.打印是I / O,所以GIL可以在发生时被释放.这意味着潜在的两个或更多的线程可以在同一时间打印,但实际上它可能不会经常发生,并且可能不会在性能上产生太大的差异.

def getaddrinfo(self, host, port, *,

family=0, type=0, proto=0, flags=0):

if self._debug:

return self.run_in_executor(None, self._getaddrinfo_debug,

host, port, family, type, proto, flags)

else:

return self.run_in_executor(None, socket.getaddrinfo,

host, port, family, type, proto, flags)

它使用默认的ThreadPoolExecutor为这个,which only has five threads:

# Argument for default thread pool executor creation.

_MAX_WORKERS = 5

这不是这个用例所需的并行几何.为了使其更像线程版本,您需要使用具有1000个线程的ThreadPoolExecutor,通过loop.set_default_executor将其设置为默认执行程序:

loop = asyncio.get_event_loop()

loop.set_default_executor(ThreadPoolExecutor(1000))

coroutines = asyncio.wait([getaddr(loop, i+site) for i in create_host(char)])

loop.run_until_complete(coroutines)

现在,这将使行为更相当于线程,但这里的现实是您真的不使用异步I / O – 您只是使用不同的API线程.所以在这里你可以做的最好的是与线程示例相同的性能.

最后,在每个示例中,你并没有真正运行等效的代码 – 线程版本正在使用一个工作池,它们共享一个queue.Queue,而asyncio版本为url列表中的每个项目生成一个协同程序.如果我使asyncio版本使用asyncio.Queue和协同池池,除了删除打印语句和制作更大的默认执行程序之外,我的两个版本的性能基本相同.这是新的asyncio代码:

import asyncio

import string

import time

from concurrent.futures import ThreadPoolExecutor

start = time.time()

def create_host(char):

for i in char:

yield i

for i in create_host(char):

if len(i)>1:

return False

for c in char:

yield c + i

char = string.digits + string.ascii_lowercase

site = '.google.com'

@asyncio.coroutine

def getaddr(loop, q):

while True:

url = yield from q.get()

if not url:

break

try:

res = yield from loop.getaddrinfo(url,80)

except:

pass

@asyncio.coroutine

def load_q(loop, q):

for host in create_host(char):

yield from q.put(host+site)

for _ in range(NUM):

yield from q.put(None)

NUM = 1000

q = asyncio.Queue()

loop = asyncio.get_event_loop()

loop.set_default_executor(ThreadPoolExecutor(NUM))

coros = [asyncio.async(getaddr(loop, q)) for i in range(NUM)]

loop.run_until_complete(load_q(loop, q))

loop.run_until_complete(asyncio.wait(coros))

end = time.time()

print(end-start)

并输出:

dan@dandesk:~$python3 threaded_example.py

20.409344911575317

dan@dandesk:~$python3 asyncio_example.py

20.39924192428589

注意,由于网络有一些变异性.他们都有时比这慢几秒钟.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值