为什么这种并行搜索和替换没有使用 100% 的 CPU?

2024-01-13

我有一个很长的推文列表(200 万条),我使用正则表达式来搜索和替换这些推文中的文本。

我使用一个运行这个joblib.平行图 https://joblib.readthedocs.io/en/latest/parallel.html (joblib是 scikit-learn 使用的并行后端)。

我的问题是,我可以在 Windows 的任务管理器中看到我的脚本没有使用 100% 的每个 CPU。它不会使用 100% 的 RAM 或磁盘。所以我不明白为什么它不会走得更快。

某处可能存在同步延迟,但我找不到什么或在哪里。

代码:

# file main.py
import re
from joblib import delayed, Parallel

def make_tweets():
    tweets = load_from_file()  # this is list of strings

    regex = re.compile(r'a *a|b *b')  # of course more complex IRL, with lookbehind/forward
    mydict = {'aa': 'A', 'bb': 'B'}  

    def handler(match):
        return mydict[match[0].replace(' ', '')]

    def replace_in(tweet)
        return re.sub(regex, handler, tweet)

    # -1 mean all cores
    # I have 6 cores that can run 12 threads
    with Parallel(n_jobs=-1) as parallel:
        tweets2 = parallel(delayed(replace_in)(tweet) for tweet in tweets)

    return tweets2

这是任务管理器:


Edit: 最后一句话

答案是工作进程减慢了joblib同步:joblib 将推文分成小块(一条一条?)发送给工作人员,这让他们等待。使用multiprocessing.Pool.map块大小为len(tweets)/cpu_count()使worker 100% 使用CPU。

Using joblib,运行时间约为1200万。如果使用多处理,则为 400 万。和multiprocessing,每个工作线程消耗大约50mb内存。


玩了一段时间后我想这是因为joblib将所有时间都花在协调所有事情的并行运行上,而没有时间实际做任何有用的工作。至少对于 OSX 和 Linux 下的我来说 — 我没有任何 MS Windows 机器

我首先加载包、拉入代码并生成一个虚拟文件:

from random import choice
import re

from multiprocessing import Pool
from joblib import delayed, Parallel

regex = re.compile(r'a *a|b *b')  # of course more complex IRL, with lookbehind/forward
mydict = {'aa': 'A', 'bb': 'B'}  

def handler(match):
    return mydict[match[0].replace(' ', '')]

def replace_in(tweet):
    return re.sub(regex, handler, tweet)

examples = [
    "Regex replace isn't that computationally expensive... I would suggest using Pandas, though, rather than just a plain loop",
    "Hmm I don't use pandas anywhere else, but if it makes it faster, I'll try! Thanks for the suggestion. Regarding the question: expensive or not, if there is no reason for it to use only 19%, it should use 100%"
    "Well, is tweets a generator, or an actual list?",
    "an actual list of strings",
    "That might be causing the main process to have the 419MB of memory, however, that doesn't mean that list will be copied over to the other processes, which only need to work over slices of the list",
    "I think joblib splits the list in roughly equal chunks and sends these chunks to the worker processes.",
    "Maybe, but if you use something like this code, 2 million lines should be done in less than a minute (assuming an SSD, and reasonable memory speeds).",
    "My point is that you don't need the whole file in memory. You could type tweets.txt | python replacer.py > tweets_replaced.txt, and use the OS's native speeds to replace data line-by-line",
    "I will try this",
    "no, this is actually slower. My code takes 12mn using joblib.parallel and for line in f_in: f_out.write(re.sub(..., line)) takes 21mn. Concerning CPU and memory usage: CPU is same (17%) and memory much lower (60Mb) using files. But I want to minimize time spent, not memory usage.",
    "I moved this to chat because StackOverflow suggested it",
    "I don't have experience with joblib. Could you try the same with Pandas? pandas.pydata.org/pandas-docs/…",
]

with open('tweets.txt', 'w') as fd:
    for i in range(2_000_000):
        print(choice(examples), file=fd)

(看看你是否能猜出我从哪里得到这些台词!)

作为基线,我尝试使用简单的解决方案:

with open('tweets.txt') as fin, open('tweets2.txt', 'w') as fout:
    for l in fin:
        fout.write(replace_in(l))

在我的 OSX 笔记本电脑上这需要 14.0 秒(挂钟时间),在我的 Linux 桌面上需要 5.15 秒。请注意,更改您的定义replace_in使用做regex.sub(handler, tweet)代替re.sub(regex, handler, tweet)在我的笔记本电脑上将上述时间减少到 8.6 秒,但我不会在下面使用此更改。

然后我尝试了你的joblib包裹:

with open('tweets.txt') as fin, open('tweets2.txt', 'w') as fout:
    with Parallel(n_jobs=-1) as parallel:
        for l in parallel(delayed(replace_in)(tweet) for tweet in fin):
            fout.write(l)

在我的笔记本电脑上需要 1 分 16 秒,在台式机上需要 34.2 秒。 CPU 利用率非常低,因为子/工作任务大部分时间都在等待协调器向它们发送工作。

然后我尝试使用multiprocessing包裹:

with open('tweets.txt') as fin, open('tweets2.txt', 'w') as fout:
    with Pool() as pool:
        for l in pool.map(replace_in, fin, chunksize=1024):
            fout.write(l)

在我的笔记本电脑上花费了 5.95 秒,在台式机上花费了 2.60 秒。我还尝试了块大小为 8 的情况,分别花费了 22.1 秒和 8.29 秒。块大小允许池将大量工作发送给其子级,因此它可以花费更少的时间进行协调,并花更多的时间来完成有用的工作。

因此我大胆猜测joblib对于这种用法并不是特别有用,因为它似乎没有 chunksize 的概念 https://github.com/joblib/joblib/issues/50.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这种并行搜索和替换没有使用 100% 的 CPU? 的相关文章

  • 通过pip安装lxml时出错:需要Microsoft Visual C++ 14.0

    我使用的是 Windows 10 机器 最近从 python 2 7 迁移到 3 5 当尝试通过 pip 安装 lxml 时 它会停止并抛出此错误消息 构建 lxml etree 扩展错误 需要 Microsoft Visual C 14
  • pandas 用 nan 值切割了一系列

    我想将 pandas cut 函数应用于包含 NaN 的序列 期望的行为是它对非 NaN 元素进行存储并为 NaN 元素返回 NaN import pandas as pd numbers with nan pd Series 3 1 2
  • Python:合并嵌套列表

    初学者在这里 我有 2 个要合并的嵌套列表 list1 a b c d e f g h list2 p q r s t u v w 我正在寻找的输出是 list3 a p q b c r s d e t f g h u v w 这可以在没有
  • Django:如何从管理界面调用管理自定义命令执行?

    参考 从代码执行管理命令 https stackoverflow com questions 907506 how can i call a custom django manage py command directly from a t
  • Pytorch“展开”等价于 Tensorflow [重复]

    这个问题在这里已经有答案了 假设我有大小为 50 50 的灰度图像 在本例中批量大小为 2 并且我使用 Pytorch Unfold 函数 如下所示 import numpy as np from torch import nn from
  • 如何在Python中打印出字母表中的第n个字母?

    ASCII 数学似乎在 Python 中不起作用 一 5 不起作用 如果没有字母数组 如何快速打印出字母表中的第 n 个字母 我天真的解决方案是这样的 letters A B C D E F G H I J K L M N O P Q R
  • 如何开始使用“scipy”

    我之前安装过 Python 3 4 2 和 3 5 2 在这两种情况下 我都可以在 Idle 中涉足编写和测试代码 这给了我两个窗口 一个用于代码的 运行 窗口 一个用于交互和测试的 Shell 窗口 输出 抱歉 不确定术语是否正确 现在我
  • 使用多索引列对多列求和

    我有一个从数据透视表创建的数据框 看起来类似于 import pandas as pd d company1 False Negative April 2012 112 0 April 2013 370 0 April 2014 499 0
  • 在pycharm中使用多处理时如何调试

    我正在 pycharm 社区版中使用 anaconda2 调试多进程程序 它有几个后台工作进程 工作进程将检查输入队列以检索任务 而不会休眠 直到收到任务 事实上 我只对主要流程感兴趣 但是pycharm调试器总是单步进入子进程 看起来主进
  • 使用 Python 3.7+ 中的 wfastcgi 以及 Numpy、Pandas 等在 IIS 上部署 Python Flask 应用程序

    使用 wfastcgi 在 IIS 上部署 python 3 7 Flask 或 Dash 应用程序时 有许多很棒的教程可以让 hello work 程序正常运行 例如 https medium com bilalbayasut deplo
  • Pytest 插件:覆盖 pytest_runtest_call 和朋友

    我正在为我的一个项目使用 pytest 开发一个测试套件 由于项目的性质 我需要创建一个 Pytest 插件来控制测试的运行方式 它们不是在本地运行 而是发送到不同的进程来运行 我知道关于xdist但我认为这并不能解决我的问题 我一直在通过
  • python 中打印变量和字符串

    好吧 我知道如何打印变量和字符串 但是我如何打印类似 我的字符串 card price 的内容 它是我的变量 我的意思是 这是我的代码 print I have and here I would like to print my varia
  • 为什么 Python 的 argparse 对 SystemExit 使用错误代码 2?

    当我给 Python 的 argparse 输入它不喜欢的输入时 它会引发一个代码为 2 的 SystemExit 其中似乎意味着 没有这样的文件或目录 https docs python org 2 library errno html
  • 返回 OSError 异常类的子类实例的逻辑在哪里?

    我一直在寻找一些对某些人来说可能相对愚蠢的东西 但对我来说非常有趣 输入和输出错误已合并为OSError在 Python 3 3 中 异常类层次结构发生了变化 关于内置类的一个有趣的特性OSError是这样 它在传递时返回它的子类errno
  • 当前异常上下文掩盖了先前的错误

    以下是我在 Doug Hellman 网站上名为 masking exceptions catch py 的文件中找到的示例 我暂时无法找到链接 throws 中引发的异常将被丢弃 而 cleanup 中引发的异常将被报告 道格在他的文章中
  • 在 python 中将数组作为参数传递

    我是Python新手 现在我需要声明大小为 20 的数组并将该数组传递给函数 需要数组的函数如下 function args The args是一个输入function 谁能帮我 如何在 python 中传递数组 当你说 数组 时 我假设你
  • 使用 javascript 在字符串中查找电子邮件地址

    我想做的是从字符串中提取电子邮件地址SomeName First email protected cdn cgi l email protection 这是我已经尝试过的代码 var stringToSearchIn SomeName Fi
  • php 中是否可以使用正则表达式替换短语后面的单词?

    输入文本 工程学院 医学院 所需产出 教育学院 教育学院 规则 school of 后面的任何单词都需要替换为 education inputext school of engineering school of medicine rule
  • Python二进制数据读取

    urllib2 请求接收二进制响应 如下所示 00 00 00 01 00 04 41 4D 54 44 00 00 00 00 02 41 97 33 33 41 99 5C 29 41 90 3D 71 41 91 D7 0A 47 0
  • 无法比较类型“ndarray(dtype=int64)”和“str”

    Example of data that I want to replace 数据具有以下属性 购买 V 高 高 中 低 维持 V 高 高 中 低 门 2 3 4 5 更多 2 4人以上 lug boot 小 中 大 安全性低 中高 这就是

随机推荐

  • let forms :如何访问宏中的解构符号?

    我正在尝试编写一个宏 它通过解构扩展为 let 形式 我的问题是我想要获得在 let 形式中定义的符号列表 包括通过解构获得的符号 Use case 我正在尝试排除这种行为 例如进行验证 let a foo bar x x y y u u
  • PHP PDO 与 foreach 和 fetch

    以下代码
  • UnicodeDecodeError:“utf8”编解码器无法解码字节 0x9c

    我有一个套接字服务器 应该从客户端接收 UTF 8 有效字符 问题是一些客户端 主要是黑客 通过它发送了所有错误类型的数据 我可以轻松区分真正的客户端 但我将发送的所有数据记录到文件中 以便稍后进行分析 有时我会遇到这样的角色 导致Unic
  • 如何在mysql中进一步过滤GROUP BY记录?

    请检查我想要查询id 43 的完整行 以及另一个nic id最大query id行 的图像 但它只给我最大query id 我尝试了不同的查询 例如 SELECT Query id nic id date subject followup
  • Python-将Excel文件的不同工作表保存为单独的Excel文件

    新手 我有一个 Excel 文件 其中有 100 多个不同的工作表 每张纸包含多个表格和图表 我希望将每张工作表另存为新的 Excel 文件 我尝试了很多Python代码 但没有一个起作用 请在这方面提供帮助 谢谢 编辑1 为了回应评论 这
  • 检查字符串是否包含子字符串。另外,获取索引和匹配数(Raku)

    常见问题解答 在 Raku 中 如何检查String https docs perl6 org type Str包含子字符串 在哪里以及多少次 我想要 3 个功能 例如 xxx bool az and az and az again az
  • GNU、GCC 和 MinGW 之间有什么区别?

    我得知 GCC 不仅是一个编译器c questions tagged c但也适用于许多其他语言 这是真的吗 如果是这样 那么它是如何完成的呢 GNU 不是编译器 它是一个操作系统和一组自由软件 旨在 类 Unix 而不使用 Unix GNU
  • 64位函数返回32位指针

    这个函数被埋在一个复杂的嵌套中 所以实际上找到原因可能超出了我所能要求的范围 但我想知道是否有人能够提供一些关于我如何调试它的提示 这是我遇到问题的代码的要点 func1 c somestruct func1 somestruct myst
  • iOS - 如何判断本地通知是否导致我的应用程序进入前台?

    我的应用程序委托中有代码 application didReceiveLocalNotification 方法来显示UI警报视图对于本地通知 每当我的应用程序位于前台时 如果本地通知到达时我的应用程序在后台运行 则用户会收到该通知 并且能够
  • 如何仅使用 HTML 在 mozilla firefox 中打开本地文件?

    我正在尝试在 ubuntu 机器上使用 html 打开 Firefox 本地磁盘上的文件 但是 我面临文件未找到错误 我的代码如下 a href home abc workspace logfile log LOG FILE a 我尝试使用
  • 无法从包含库的应用程序启动意图

    您好 我想启动一项位于连接的图书馆项目中的服务 所有相关课程都在图书馆 该服务是从位于库中的活动调用的 Intent serviceIntent new Intent serviceIntent setAction org example
  • 如何在两个 Pandas DataFrame 对象上执行 SQL 样式不相交或设置差异?

    我正在尝试使用 Pandas 来解决一个白痴 DBA 没有对现已崩溃的数据集进行备份的问题 因此我正在尝试查找两列之间的差异 由于我不会详细说明的原因 我使用的是 Pandas 而不是数据库 我想做的是 考虑到 Dataset A A B
  • 自动装配 Spring JPA 存储库的 @Primary 等效项

    我在应用程序中使用 Spring JPA 存储库和实体 现在 在该应用程序的某种风格中 我需要扩展我的一个实体并提供一个扩展存储库 对于我需要覆盖 扩展的所有其他 bean 我只需创建一个新的实现并使用 Primary 对其进行注释 以便它
  • Android - 如何检索货币汇率[重复]

    这个问题在这里已经有答案了 我正在尝试为 Android 开发一个简单的外汇应用程序 首先 我需要获取过去一年的货币汇率 有人可以建议我该怎么做吗 我查看了 Google Financh API 但找不到如何检索货币汇率 任何建议表示赞赏
  • Clojure 时间和日期库是什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我找不到处理时间和日期的库http clojure org libraries http clojur
  • 每个 SQL Server 外键都应该有一个匹配的索引吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在 SQL Server 数据库中为每个外键都有一个索引有哪些优点 如果有的话 是的 这是一个很好的做法 请参阅此处 SQL Server 何时
  • React 在 prop 更新时重新渲染组件

    我的想法 理解是 只要 props 或状态发生变化 React 组件就会更新 所以我声明我的变量 let percentage width 10 并有一个setInterval运行这么长时间后更改该变量的函数 setInterval fun
  • MongoDB Compass 社区身份验证失败

    我刚刚创建了一个新的 MongoDB 帐户 现在尝试连接通过 MongoDB Compass 社区应用程序创建的免费集群 但显示 身份验证失败 错误 这是我到目前为止检查过的 在我的 MongoDB Clusters 部分 当我单击 Con
  • Sparklyr 无法看到在 Hive 中创建的数据库,反之亦然

    我在本地安装了 Apache Hive 并尝试通过 Rstudio sparklyr 读取表 我使用 Hive 创建了一个数据库 hive gt CREATE DATABASE test 我尝试使用以下 R 脚本读取该数据库 library
  • 为什么这种并行搜索和替换没有使用 100% 的 CPU?

    我有一个很长的推文列表 200 万条 我使用正则表达式来搜索和替换这些推文中的文本 我使用一个运行这个joblib 平行图 https joblib readthedocs io en latest parallel html joblib