Home  >  Article  >  Backend Development  >  When should you use Python 3.5\'s `await` feature for asyncio, and when should you avoid it?

When should you use Python 3.5\'s `await` feature for asyncio, and when should you avoid it?

Barbara Streisand
Barbara StreisandOriginal
2024-11-17 04:41:03814browse

When should you use Python 3.5's `await` feature for asyncio, and when should you avoid it?

When to Utilize and Avoid Python 3.5's await Feature for Asyncio

Python 3.5 introduced the await keyword to facilitate asynchronous programming with asyncio. However, it's not always clear what operations should be awaited to maximize efficiency.

Determining Asynchronous Candidates

A rule of thumb is to await any function that performs an I/O operation, such as accessing the network or reading files. These operations can potentially block synchronous code for an extended period. By awaiting them, asyncio can perform other operations concurrently.

Advantages of Asynchronous Code

As demonstrated in the code snippet below, asynchronous code can significantly speed up operations that involve multiple I/O calls:

# Synchronous way:
download(url1)  # takes 5 sec.
download(url2)  # takes 5 sec.
# Total time: 10 sec.

# Asynchronous way:
await asyncio.gather(
    async_download(url1),  # takes 5 sec. 
    async_download(url2)   # takes 5 sec.
)
# Total time: only 5 sec. (+ little overhead for using asyncio)

Functions with Mixed Async/Synchronous Code

Asynchronous functions can call both asynchronous and synchronous functions. However, there's no advantage in awaiting synchronous code that doesn't perform I/O operations. This can introduce unnecessary overhead:

async def extract_links(url):  

    # async_download() was created async to get benefit of I/O
    html = await async_download(url)  

    # parse() doesn't work with I/O, there's no sense to make it async
    links = parse(html)  

    return links

Avoid Long-Running Synchronous Operations

It's crucial to avoid long-running synchronous operations (> 50 ms) within asynchronous functions, as they can freeze all other asynchronous tasks. To handle these tasks efficiently:

  • Use Multiprocessing: Execute long-running operations in a separate process and await the result:
executor = ProcessPoolExecutor(2)

async def extract_links(url):
    data = await download(url)
    links = parse(data)
    # Now your main process can handle another async functions while separate process running    
    links_found = await loop.run_in_executor(executor, search_in_very_big_file, links)
  • Use ThreadPoolExecutor: For I/O-bound synchronous tasks, such as requests to a web server:
executor = ThreadPoolExecutor(2)

async def download(url):
    response = await loop.run_in_executor(executor, requests.get, url)
    return response.text

The above is the detailed content of When should you use Python 3.5\'s `await` feature for asyncio, and when should you avoid it?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn