从两个简单例子窥视协程的惊人性能(Python)

简介:

   我们用普通同步方式扫描10个端口,用协程(异步)方式扫描1000个端口,对比时间。

1、同步方式代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

#encoding=utf-8

#author: walker

#date: 2014-07-16

#function: 使用同步方式扫描10个端口

 

import time, socket, sys

 

def task(addr):

   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

   sock.settimeout(100)

   try:

       sock.connect(addr)

       print('Port ' + str(str(addr[1])) + ' is  open')

   except:

       pass

   finally:

       sock.close()

 

#扫描10个端口

def synchronous():

   for i in range(0, 10):

       task(('127.0.0.1', i))

        

t0 = time.time()

synchronous()

t1 = time.time()

print('time: {}s'.format(t1 - t0))

walker机器的测试结果为9.0110001564s ≈ 9s


2、协程(异步)方式代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

#encoding=utf-8

#author: walker

#date: 2014-07-16

#function: 使用协程(异步)方式扫描1000个端口

 

import gevent.monkey

gevent.monkey.patch_socket()

 

import gevent, socket, sys, time

 

def task(addr):

   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

   sock.settimeout(100)

   try:

       sock.connect(addr)

       print('Port ' + str(str(addr[1])) + ' is  open')

   except:

       pass

   finally:

       sock.close()

        

#扫描1000个端口

def asynchronous():

   threads = []

   for i in range(0, 1000):

       threads.append(gevent.spawn(task, ('127.0.0.1', i)))

   gevent.joinall(threads)

 

t0 = time.time()

asynchronous()

t1 = time.time()

print('time: {}s'.format(t1 - t0))

walker机器的测试结果为2.08499979973s ≈ 2s


用同步方式扫描10个端口需要9s,而用协程扫描1000个端口仅需2s!从代码复杂性来看,asynchronous函数仅比synchronous函数多一行。也就是说协程以同步方式的代码复杂度实现了异步程序的性能!


Windows下使用gevent,建议安装二进制版本,先装greenlet,再装gevent:



相关阅读:

1、Gevent tutorial中文翻译

2、Python协程:从yield/send到async/await


*** walker * 2014-07-16 ***

本文转自walker snapshot博客51CTO博客,原文链接http://blog.51cto.com/walkerqt/1439034如需转载请自行联系原作者


RQSLT

相关文章
|
机器学习/深度学习 数据采集 算法
Python AutoML框架选型攻略:7个工具性能对比与应用指南
本文系统介绍了主流Python AutoML库的技术特点与适用场景,涵盖AutoGluon、PyCaret、TPOT、Auto-sklearn、H2O AutoML及AutoKeras等工具,帮助开发者根据项目需求高效选择自动化机器学习方案。
1502 1
|
数据采集 测试技术 C++
无headers爬虫 vs 带headers爬虫:Python性能对比
无headers爬虫 vs 带headers爬虫:Python性能对比
|
11月前
|
Go 调度 Python
Golang协程和Python协程用法上的那些“不一样”
本文对比了 Python 和 Go 语言中协程的区别,重点分析了调度机制和执行方式的不同。Go 的协程(goroutine)由运行时自动调度,启动后立即执行;而 Python 协程需通过 await 显式调度,依赖事件循环。文中通过代码示例展示了两种协程的实际运行效果。
421 7
|
11月前
|
传感器 数据采集 监控
Python生成器与迭代器:从内存优化到协程调度的深度实践
简介:本文深入解析Python迭代器与生成器的原理及应用,涵盖内存优化技巧、底层协议实现、生成器通信机制及异步编程场景。通过实例讲解如何高效处理大文件、构建数据流水线,并对比不同迭代方式的性能特点,助你编写低内存、高效率的Python代码。
395 0
|
10月前
|
数据采集 网络协议 API
协程+连接池:高并发Python爬虫的底层优化逻辑
协程+连接池:高并发Python爬虫的底层优化逻辑
|
11月前
|
数据采集 存储 Web App开发
Python爬虫库性能与选型实战指南:从需求到落地的全链路解析
本文深入解析Python爬虫库的性能与选型策略,涵盖需求分析、技术评估与实战案例,助你构建高效稳定的数据采集系统。
817 0
|
网络协议 API 开发者
分析http.client与requests在Python中的性能差异并优化。
合理地选择 `http.client`和 `requests`库以及在此基础上优化代码,可以帮助你的Python网络编程更加顺利,无论是在性能还是在易用性上。我们通常推荐使用 `requests`库,因为它的易用性。对于需要大量详细控制的任务,或者对性能有严格要求的情况,可以考虑使用 `http.client`库。同时,不断优化并管理员连接、设定合理超时和重试都是提高网络访问效率和稳定性的好方式。
298 19
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
306 10
|
12月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
1355 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析

推荐镜像

更多