验证 python asyncio 异步运行

问题描述 投票:0回答:1

我有一个函数,它接受 html 字符串,通过删除停止词来清理它,然后计算用户确定的搜索字符串中单词出现的次数:

def clean_text(string, search_term):
    """
    This function removes stop words and non alphanumeric characters from a string and counts the number of times each word in a specified search term appears in the string.
    :param string: the string to clean
    :param search_term:
    """
    stop_words = set(stopwords.words('english'))
    word_tokens = word_tokenize(string)
    alpha_string = [word.lower() for word in word_tokens if word.isalpha()]
    cleaned_string = [word.lower() for word in alpha_string if word.lower() not in stop_words]
    
    c = Counter(cleaned_string)
    total_freq = np.sum([c[i] for i in search_term.lower().split()])
    
    if total_freq == 0:
        return (0, 0)
    else:
        return " ".join(cleaned_string), total_freq

我正在尝试使用 python 的 asyncio 将其转换为异步函数。我有以下代码:

async def clean_text_async(string, search_term):
    """
    This function removes stop words and non alphanumeric characters from a string and counts the number of times each word in a specified search term appears in the string.
    :param string: the string to clean
    :param search_term:
    """
    stop_words = set(stopwords.words('english'))
    word_tokens = word_tokenize(string)
    alpha_string = [word.lower() for word in word_tokens if word.isalpha()]
    cleaned_string = [word.lower() for word in alpha_string if word.lower() not in stop_words]
    
    c = Counter(cleaned_string)
    total_freq = np.sum([c[i] for i in search_term.lower().split()])
    
    if total_freq == 0:
        return (0, 0)
    else:
        return " ".join(cleaned_string), total_freq
    
async def async_main_html(df_html):
    clean_text_tasks = []
    
    for html in df_html['html']:
        task = asyncio.create_task(clean_text_async(string = html, search_term = search_term))
        clean_text_tasks.append(task)
        
    results = await asyncio.gather(*clean_text_tasks)
    return results

cleaned_text = await async_main_html(df_html)

代码可以使用上述命令运行并运行,但我不认为它是异步运行的,因为使用 async_main_html 和 clean_text 运行该函数需要相同的时间。

我做错了什么吗?

python html asynchronous python-asyncio
1个回答
0
投票

您没有了解异步编程的作用 - 事实上,它对此代码根本没有任何好处!

异步代码是单线程的,当一个任务必须等待外部源(文件系统、数据库、HTTP API 等)提供数据时,只允许代码并发运行。此时它将使用

await
语句(或等效语句)获取数据,虽然该数据尚未准备好,但其他任务有机会运行。

您的代码只是进行处理 - 使用

await
语句是没有意义的 - 因此首先异步运行它是没有意义的。

但是,在一种情况下,它可能会受益匪浅:如果此处理是作为 API 中处理请求的一部分进行的,并且可能需要同时处理其中多个请求,则可以使用 asyncio在其他线程中运行某些 CPU 密集型处理。例如,由于 Python 中的正则表达式引擎在本机代码中运行,因此它将释放 GIL,从而在某种程度上允许正则表达式在后台并行运行,并且您可以获得一些改进 - 如果您在以下位置发出其中几个任务一次。然而,完成单个任务的时间将保持不变。

如果您选择以这种方式重新构建代码,而不是像您所做的那样将

clean_text
更改为协同例程函数,只需按原样运行(同步,使用普通的
def
而不是
async def 
),但可以使用
asyncio.create_task(asyncio.run_in_executor(None, clean_text, *args))
调用从异步代码中调用它。 如果这在某种程度上有效,您可能需要微调自定义“执行器”,而不是使用带有 None 的默认“执行器”来提取一些额外的性能。

© www.soinside.com 2019 - 2024. All rights reserved.