天天看点

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

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

1、同步方式代码

<code>#encoding=utf-8</code>

<code>#author: walker</code>

<code>#date: 2014-07-16</code>

<code>#function: 使用同步方式扫描10个端口</code>

<code>import</code> <code>time, socket, sys</code>

<code>def</code> <code>task(addr):</code>

<code>    </code><code>sock </code><code>=</code> <code>socket.socket(socket.AF_INET, socket.SOCK_STREAM)</code>

<code>    </code><code>sock.settimeout(</code><code>100</code><code>)</code>

<code>    </code><code>try</code><code>:</code>

<code>        </code><code>sock.connect(addr)</code>

<code>        </code><code>print</code><code>(</code><code>'Port '</code> <code>+</code> <code>str</code><code>(</code><code>str</code><code>(addr[</code><code>1</code><code>])) </code><code>+</code> <code>' is  open'</code><code>)</code>

<code>    </code><code>except</code><code>:</code>

<code>        </code><code>pass</code>

<code>    </code><code>finally</code><code>:</code>

<code>        </code><code>sock.close()</code>

<code>#扫描10个端口</code>

<code>def</code> <code>synchronous():</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>0</code><code>, </code><code>10</code><code>):</code>

<code>        </code><code>task((</code><code>'127.0.0.1'</code><code>, i))</code>

<code>        </code> 

<code>t0 </code><code>=</code> <code>time.time()</code>

<code>synchronous()</code>

<code>t1 </code><code>=</code> <code>time.time()</code>

<code>print</code><code>(</code><code>'time: {}s'</code><code>.</code><code>format</code><code>(t1 </code><code>-</code> <code>t0))</code>

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

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

<code>import</code> <code>gevent.monkey</code>

<code>gevent.monkey.patch_socket()</code>

<code>import</code> <code>gevent, socket, sys, time</code>

<code>#扫描1000个端口</code>

<code>def</code> <code>asynchronous():</code>

<code>    </code><code>threads </code><code>=</code> <code>[]</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>0</code><code>, </code><code>1000</code><code>):</code>

<code>        </code><code>threads.append(gevent.spawn(task, (</code><code>'127.0.0.1'</code><code>, i)))</code>

<code>    </code><code>gevent.joinall(threads)</code>

<code>asynchronous()</code>

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

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

<a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#greenlet" target="_blank">http://www.lfd.uci.edu/~gohlke/pythonlibs/#greenlet</a>

<a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#gevent" target="_blank">http://www.lfd.uci.edu/~gohlke/pythonlibs/#gevent</a>

相关阅读:

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

RQSLT