美文网首页
对比python的I/O密集型单线程和aysncio协程并发

对比python的I/O密集型单线程和aysncio协程并发

作者: 余生还长你别慌 | 来源:发表于2019-08-21 15:44 被阅读0次

前面比较了单线程与多线程的I/O密集型,多线程访问速度远远优于单线程,今天我们再测试下单线程与协程并发访问多个网页看看结果如何。做这个测试的原因是,很多爬虫高手会推荐用协程,并且go语言并发高性能也是用的协程,横向比较的话,协程比线程耗费资源少。纵向比较,go语言的高并发协程耗费资源少于python语言。所以将来go语言可能会在高并发领域应用越来越广。扯远了哈。我们进入正题,说下比较思路:

  1. get_url获取基金网站的首页内容和返回结果(当然后面的协程函数get_each_url会引用get_url,作用是获取每个基金连接的网页内容);
  2. handle_response 是处理get_url获取的首页内容,从中提取每个基金的链接等内容;
  3. 协程函数get_each_url,后面将每个基金的url传入这个函数,并发访问;
  4. main里面分两部分,一部分是单线程访问30个网页,一个是协程并发访问;
  5. 协程部分主要用了asyncio这个模块。定义一个task列表,列表中存放的是每个协程函数返回的协程对象,后面会把这个列表扔进协程loop中自动循环执行
# -*- encoding=UTF-8 -*-
__author__ = 'wjj1982'
__date__ = '2019/8/19 20:46'
__product__ = 'PyCharm'
__filename__ = '协程'

from bs4 import BeautifulSoup as bs
import requests
import re
import time
import asyncio


# 输入一个url,然后get页面信息,最后返回页面content和页面code
def get_url(url):
    if url is None:
        return None
    try:
        response = requests.get(url)
    except Exception as e:
        print('get url failed,error is:{}'.format(e))
        return None
    if response.status_code != 200:
        return None
    return response.status_code, response.content

def handle_response(content):
    bs_content = bs(content, 'html.parser', from_encoding='gb18030')
    urls_fund = bs_content.find_all('ul', class_='num_right')

    fund_list = []

    for url_fund in urls_fund:
        for each_li in url_fund.find_all('li'):
            fund_info_dict = {'fund_id': '',
                              'fund_name': '',
                              'fund_url': ''}
            each_a = each_li.find_all('a')
            if len(each_a) > 0:
                each_a = each_a[0]
                fund_info_dict['fund_id'] = re.findall(r'\d+', each_a.text)[0]
                fund_info_dict['fund_name'] = each_a.text.split(')')[1]
                fund_info_dict['fund_url'] = each_a['href']
                # fund_info_dict['fund_url'] = each_a.attrs['href']
                fund_list.append(fund_info_dict)
    return fund_list

# 定义一个协程函数,传入url,调用get_url访问页面并返回访问结果和页面内容
async def get_each_url(url):
    code_response1, content_response1 = get_url(url)
    print(code_response1)


if __name__ == '__main__':
    # 这一部分是获取所有基金的url
    url = 'http://****.com/****
    code_response, content_response = get_url(url)
    fund_list = handle_response(content_response)

    # 单线程处理30个url
    print('单线程开始处理30个url')
    start = time.time()
    for fund in fund_list[:29]:
        code_response, content_response = get_url(fund['fund_url'])
        print(code_response)
    end = time.time()
    print('单线程处理30个url时的耗时:{}'.format(end - start))

    # 多协程处理30个url
    print('多协程处理30个url')
    start1 = time.time()
    # 定义一个task列表,列表中存放的是每个协程函数返回的协程对象,后面会把这个列表扔进协程loop中自动循环执行
    task_list = []

    # 协程函数get_each_url返回对象coroutine,然后存入task列表
    for fun in fund_list[:29]:
        coroutine = get_each_url(fun['fund_url'])
        task_list.append(asyncio.ensure_future(coroutine))

    # 开启一个协程loop循环,然后把task列表扔进这个loop中,并run开始执行
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(task_list))

    end1 = time.time()
    print('多协程处理30个url时的耗时:{}'.format(end1 - start1))
多协程与单线程比较结果.jpg

相关文章

  • 对比python的I/O密集型单线程和aysncio协程并发

    前面比较了单线程与多线程的I/O密集型,多线程访问速度远远优于单线程,今天我们再测试下单线程与协程并发访问多个网页...

  • 索引 - Python

    文集主页 Python 解释器和三种栈多进程、多线程、协程、并发并行Python I/O 操作(一)Python ...

  • python 协程和异步I/O的实践

    python 协程和异步I/O的实践 协程的概念 协程(coroutine)通常又称之为微线程或纤程,它是相互协作...

  • 写给Android开发者的协程基本原理

    前言 协程是一个并发方案。也是一种思想。 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率...

  • Android中的Coroutine协程原理详解

    前言 协程是一个并发方案。也是一种思想。 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率...

  • Android中的Coroutine协程原理详解

    前言 协程是一个并发方案。也是一种思想。 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率...

  • 关于协程开发

    协程: 1.什么是协程 协程,经常被称为微线程,纤程,是一种多任务并发的操作手段定义:协程是运行在单线程中的并发程...

  • 对比python的计算密集型单线程和多线程

    python的并发有三种方式:线程,进程和协程。今天记录下python多线程和单线程对比结果,当然这里测试的时计算...

  • 协程在python中的演化

    维基百科协程定义: web服务以I/O是瓶颈,而这这是协程所擅长的:多任务并发,每个任务在合适的时候挂起(发起I/...

  • 并发编程之Concurrent.futures vs Multi

    并发编程是刚需,尤其是在多I/O操作时,多线程,协程,多进程三路英雄各显神通。多线程,协程属于并发操作,多进程属于...

网友评论

      本文标题:对比python的I/O密集型单线程和aysncio协程并发

      本文链接:https://www.haomeiwen.com/subject/wuqisctx.html