V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Feiox
V2EX  ›  Python

为什么基于协程的爬虫要比基于线程的爬虫慢?

  •  
  •   Feiox ·
    feiox · 2014-12-09 11:03:03 +08:00 · 5317 次点击
    这是一个创建于 3639 天前的主题,其中的信息可能已经有所发展或是发生改变。
    实测:
    20 个协程 * 1000 个任务 = 23 秒
    20 个线程 * 1000 个任务 = 12 秒

    10个协程 cpu 占用 2.3%
    20 个线程 cpu 占用 56 %

    测试代码为最简单 get 网页( with gevent.pool & reqeusts)
    21 条回复    2014-12-30 10:35:14 +08:00
    felixzhu
        1
    felixzhu  
       2014-12-09 11:21:39 +08:00
    切换成本?
    phoneli
        2
    phoneli  
       2014-12-09 11:42:17 +08:00
    网络io处理的问题?
    imn1
        3
    imn1  
       2014-12-09 11:46:40 +08:00
    你那个不是乘的关系吧?
    12秒 1k任务挺难想象的……爬什么网?
    如果只是本地,实际上只是磁盘IO……
    est
        4
    est  
       2014-12-09 11:48:06 +08:00
    目测代码姿势奇特。
    clino
        5
    clino  
       2014-12-09 11:48:08 +08:00
    因为协程只能用一个cpu吧
    所以适合与高IO低CPU的任务
    wuyadong
        6
    wuyadong  
       2014-12-09 11:48:59 +08:00
    requests是阻塞的吧。这样用没有用到协程的效果吧。
    clino
        7
    clino  
       2014-12-09 11:50:19 +08:00
    是不是因为爬到本地以后要做不少耗CPU的处理导致有这样的结果?
    如果有比较耗CPU的动作,看能不能在协程中调用子进程处理,这样就不会因为高CPU阻塞本进程
    Feiox
        8
    Feiox  
    OP
       2014-12-09 12:05:10 +08:00
    @imn1 学校的网。。。是很慢的。
    @wuyadong `requests` 是阻塞的?应该和这个没关系吧。。。确实比单线程块很多。
    @clino 没有。纯粹的 get 一个网页
    richardtsai
        9
    richardtsai  
       2014-12-09 12:25:27 +08:00
    @clino +1

    request的阻塞应该可以用gevent.monkey.patch_socket()变成非阻塞~?不过我也没试过……
    dant
        10
    dant  
       2014-12-09 12:29:59 +08:00 via iPhone
    20 个线程应该完全没有压力啊...
    不过 CPython 好像有 GIL?
    tabris17
        11
    tabris17  
       2014-12-09 12:31:41 +08:00
    你协程有没有充分利用多CPU资源,协程使用的IO库是不是阻塞的
    sujin190
        12
    sujin190  
       2014-12-09 12:38:44 +08:00
    协程不是这么用的
    haython
        13
    haython  
       2014-12-09 12:47:03 +08:00
    为什么协程会比线程快?
    zhouquanbest
        15
    zhouquanbest  
       2014-12-09 14:04:19 +08:00
    为了取得平衡
    我一般是多worker(process)+gevent
    数量根据业务调配 这样比较方便

    (论人手一个Python爬虫轮子的重要性)
    clino
        16
    clino  
       2014-12-09 17:00:42 +08:00
    楼主用 grequests 试过了吗?
    njutree
        17
    njutree  
       2014-12-09 17:54:46 +08:00
    首先不同语言的协程和线程还是有区别的,其次楼主爬的什么网页io高么,最后使用协程的时候没有让他们有阻塞么?
    zenliver
        18
    zenliver  
       2014-12-10 10:15:31 +08:00
    request 阻塞的 无误
    wuyadong
        19
    wuyadong  
       2014-12-10 10:38:07 +08:00
    @Feiox request是阻塞的,异步的关键是非阻塞的IO。我不是特别清楚gevent是否能将request转成非阻塞IO,但是我觉得有可能这个阻塞IO可能是关键。:)
    dishonest
        20
    dishonest  
       2014-12-26 14:21:22 +08:00
    @wuyadong @Feiox gevent 我记得是可以转requests的。
    datou552211
        21
    datou552211  
       2014-12-30 10:35:14 +08:00 via iPhone
    协程 语言本身代替系统做了线程的工作 所以和语言的效率有关
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5605 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 08:01 · PVG 16:01 · LAX 00:01 · JFK 03:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.