You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Concurrent.futures实现循环迭代并行执行提速

问题原因

你当前的写法没有实现并行加速的核心原因是:你把整个matching函数作为单个任务提交给了线程池,全程只有1个工作线程在执行完整的循环逻辑,其余配置的worker完全处于闲置状态,根本没有参与计算。同时你提交任务后没有调用future.result(),就算任务执行完也拿不到最终的匹配结果。

正确实现方式

并行的核心是把可独立拆分的计算单元拆成单个子任务,分发给多个worker同时执行,而不是把整个计算逻辑打包成一个任务丢进线程池。
针对你的场景,完全可以把「列表a中单个字符串和列表b的多规则匹配」作为独立子任务拆分,分发给不同worker并行计算,最后在主线程合并结果即可。

修正后的可运行代码:

import random
import string
import tqdm
from thefuzz import fuzz, process
from concurrent.futures import ThreadPoolExecutor, as_completed

def generate_string(items=10, lengths=5):
    # 修正原写法生成重复字符串的问题,返回独立随机字符串
    return [''.join(random.choice(string.ascii_letters) for _ in range(lengths)) for _ in range(items)]

# 单条字符串匹配逻辑,作为最小子任务分发
def match_single_item(x, candidate_list, scorers):
    best_score = 0
    best_result = None
    for scorer in scorers.values():
        res = process.extractOne(x, candidate_list, scorer=scorer)
        if res[1] > best_score:
            best_score = res[1]
            best_result = res
    return x, best_result

def matching_parallel(a, b, max_workers=5):
    matches = {}
    scorers = {
        'token_sort_ratio': fuzz.token_sort_ratio, 
        'token_set_ratio': fuzz.token_set_ratio, 
        'partial_token_sort_ratio': fuzz.partial_token_sort_ratio,
        'Quick': fuzz.QRatio, 
        'Unicode Quick': fuzz.UQRatio, 
        'Weighted': fuzz.WRatio, 
        'Unweighted': fuzz.UWRatio
    }

    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 为每个待匹配字符串提交独立任务
        futures = [executor.submit(match_single_item, x, b, scorers) for x in a]
        # 按任务完成顺序更新进度、收集结果
        for future in tqdm.tqdm(as_completed(futures), total=len(futures)):
            x, res = future.result()
            matches[x] = res
    return matches

if __name__ == "__main__":
    list_a = generate_string(100, 10)
    list_b = generate_string(10, 5)
    final_matches = matching_parallel(list_a, list_b, max_workers=5)
注意事项
  • 原代码里的generate_string写法有误:[xxx] * items会把同一个字符串对象重复引用N次,列表内所有元素完全一致,用这种数据测试性能没有参考意义,修正版已经改成生成真正独立的随机字符串。
  • 如果你没给thefuzz安装python-Levenshtein加速依赖,默认会跑纯Python实现的字符串匹配逻辑,这种场景受Python GIL锁限制,多线程不会有明显加速,直接把ThreadPoolExecutor换成ProcessPoolExecutor用多进程跑即可。注意用多进程时,任务函数必须定义在顶层作用域,保证可被序列化。
  • 不要在子线程/子进程里直接修改外部共享的字典、列表这类可变对象,所有子任务只返回自身的计算结果,统一在主线程做结果合并,避免线程/进程安全问题导致的数据错乱。
  • worker数不是越高越好:如果是CPU密集型计算,worker数设置为和CPU核心数一致即可,开太多反而会因为频繁的上下文切换拖慢整体速度。

内容的提问来源于stack exchange,提问作者artemis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 09:51:17