title: Why is the asyncio library slower than threads for this I/O-bound operation?
body: <p>I'm writing a python program used to enumerate a site's domain name.For example,'a.google.com'.</p>
  
  <p>First, I used the <code>threading</code> module to do this:</p>
  
  <pre><code>import string
  import time
  import socket
  import threading
  from threading import Thread
  from queue import Queue
  
  '''
  enumerate a site's domain name like this:
  1-9 a-z + .google.com
  1.google.com
  2.google.com
  .
  .
  1a.google.com
  .
  .
  zz.google.com
  
  '''
  
  start = time.time()
  def create_host(char):
      '''
      if char is '1-9a-z'
      create char like'1,2,3,...,zz'
      '''
      for i in char:
          yield i
      for i in create_host(char):
          if len(i)&gt;1:
              return False
          for c in char:
              yield c + i
  
  
  char = string.digits + string.ascii_lowercase
  site = '.google.com'
  
  
  def getaddr():
      while True:
          url = q.get()
          try:
              res = socket.getaddrinfo(url,80)
              print(url + ":" + res[0][4][0])
          except:
              pass
          q.task_done()
  
  NUM=1000  #thread's num
  q=Queue()
  
  for i in range(NUM):
      t = Thread(target=getaddr)
      t.setDaemon(True)
      t.start()
  
  for host in create_host(char):
      q.put(host+site)
  q.join()
  
  end = time.time()
  
  print(end-start)
  
  '''
  used time:
  9.448670148849487
  '''
  </code></pre>
  
  <p>Later, I read a book which said in some cases coroutines are faster than threads. So, I rewrote the code to use <code>asyncio</code>:</p>
  
  <pre><code>import asyncio
  import string
  import time
  
  
  start = time.time()
  def create_host(char):
      for i in char:
          yield i
      for i in create_host(char):
          if len(i)&gt;1:
              return False
          for c in char:
              yield c + i
  
  
  char = string.digits + string.ascii_lowercase
  site = '.google.com'
  
  @asyncio.coroutine
  def getaddr(loop, url):
      try:
          res = yield from loop.getaddrinfo(url,80)
          print(url + ':' + res[0][4][0])
      except:
          pass
  
  loop = asyncio.get_event_loop()
  coroutines = asyncio.wait([getaddr(loop, i+site) for i in create_host(char)])
  loop.run_until_complete(coroutines)
  
  end = time.time()
  
  print(end-start)
  
  
  '''
  time 
  120.42313003540039
  '''
  </code></pre>
  
  <p>Why is the <code>asyncio</code> version of  <code>getaddrinfo</code> is so slow? Am I misusing the coroutines somehow?</p>