【问题标题】:How to apply a map operation in batches?如何批量应用地图操作?
【发布时间】:2019-11-28 14:48:19
【问题描述】:

我正在使用一个将对象应用于字符串列表的函数。但是,这需要很长时间才能完成,因为在检查对象的库网站后,作者说您需要分块应用它,以免内存过载。我正在应用如下功能:

list_1 =['hi how are you', 'i am good', ..., 'how is']
results = list(
    map(lambda string_list_elem: foo(string_list_elem, library_obj), list_1))

以上内容花费了太多时间。加速函数应用的最佳方法是什么?到目前为止,我尝试将列表拆分成这样的块:

import itertools

def split_seq(iterable, size):
    it = iter(iterable)
    item = list(itertools.islice(it, size))
    while item:
        yield item
        item = list(itertools.islice(it, size))

list(split_seq(list_1, 500))

但是,我不知道这是否可行。我应该做一个列表理解还是只使用这个函数并拆分?加速 results_list 过程的推荐方法是什么?

【问题讨论】:

  • 我试图了解问题是您的代码太慢还是服务的流量是问题,因为服务器不能超载。在后一种情况下,问题似乎是固有的且无法解决。在前一种情况下,你可以穿这个吗?
  • 问题不在于流量,这是在本地完成的。问题是我必须按块应用字符串,然后重新加入它们。但是,我不知道哪种方法是正确的。
  • 很多因素取决于:1) list-1 的大小是多少? 2) foo 函数在做什么? 3) 网络连接速度是多少? 4) 花费太多 - 那是多少,什么时间可以接受?
  • @anon,发布单个 foo('hi how are you', library_obj) 调用的执行时间 - 以获得大致的标称时间
  • @anon,读/写文件不是网络,而是导致 I/O

标签: python python-3.x data-structures iteration list-comprehension


【解决方案1】:

由于您无法显示/共享关键函数/worker foo(),因此我无法识别所有需要使用不同优化技术解决的潜在瓶颈
在这个阶段,我建议通过concurrent.futures.ThreadPoolExecutor 开始使用并发/异步方法:

from concurrent.futures import ThreadPoolExecutor
import functools

def foo(string_list_elem, library_obj):
    ....

str_list = ['hi how are you', 'i am good', ..., 'how is']

with ThreadPoolExecutor() as executor:
    # replace `<your_lib>` with your actual library_obj
    results = list(executor.map(functools.partial(foo, library_obj=<your_lib>), str_list))
    print(results)

它将显着加快您的处理速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2012-12-11
    • 2023-01-24
    • 2012-03-03
    相关资源
    最近更新 更多