首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与多处理一起使用时,PyTesseract调用工作非常慢

与多处理一起使用时,PyTesseract调用工作非常慢
EN

Stack Overflow用户
提问于 2018-11-25 14:23:54
回答 1查看 3.9K关注 0票数 3

我有一个函数,它接收图像列表,并在将OCR应用到图像之后,在列表中生成输出。我有另一个函数,它通过使用多处理来控制这个函数的输入。因此,当我有一个列表(即没有多处理)时,列表的每个图像都需要1s,但是当我将必须并行处理的列表增加到4个时,每个图像都得到了惊人的13s。

为了了解问题的真正所在,我尝试创建一个最小的问题工作示例。这里我有两个函数eat25eat100,它们打开一个图像name并将其提供给使用API pytesseract的OCR。eat25做了25次,eat100做了100次。

我在这里的目标是在没有多处理的情况下运行eat100,用多处理运行eat25 (有4个进程)。从理论上讲,如果我有4个不同的处理器(我有2个内核,每个内核有2个线程,因此CPU=4(如果我错了,请纠正我的错误),那么这就应该比eat100少4倍。

但是,当我看到代码在打印“0”4次后甚至没有响应时,所有的理论都白费了。不过,单处理器函数eat100工作得很好。

我已经测试了一个简单的范围立方体功能,它在多处理中工作得很好,所以我的处理器确实工作得很好。这里唯一的罪魁祸首是:

  • pytesseract:见
  • 坏密码?有些事我做得不对。

`

代码语言:javascript
运行
复制
from pathos.multiprocessing import ProcessingPool
from time import time 
from PIL import Image
import pytesseract as pt
def eat25(name):
    for i in range(25):
        print('Processing :'+str(i))
        pt.image_to_string(Image.open(name),lang='hin+eng',config='--psm 6')
def eat100(name):
    for i in range(100):
        print('Processing :'+str(i))
        pt.image_to_string(Image.open(name),lang='hin+eng',config='--psm 6')
st = time()
eat100('normalBox.tiff')
en = time()
print('Direct :'+str(en-st))
#Using pathos
def caller():
    pool = ProcessingPool()
    pool.map(eat25,['normalBox.tiff','normalBox.tiff','normalBox.tiff','normalBox.tiff'])
if (__name__=='__main__'):
    caller()
en2 = time()

print('Pathos :'+str(en2-en))

那么,问题到底在哪里?任何帮助都是非常感谢的!

编辑:图像normalBox.tiff可以找到这里。如果人们复制代码并检查问题是否继续,我将非常高兴。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-30 17:33:04

我是pathos的作者。如果您的代码需要1s连续运行,那么在天真的进程并行中运行很可能需要更长的时间。使用简单的进程并行是有开销的:

  1. 必须在每个处理器上构造一个新的python实例。
  2. 您的函数和依赖项需要序列化并发送到每个处理器。
  3. 您的数据需要序列化并发送到处理器。
  4. 反序列化也是如此
  5. 您可以从长时间池或大量数据序列化中遇到内存问题。

我建议检查一些简单的东西,以检查您的问题可能在哪里:

  • 尝试pathos.pools.ThreadPool使用线程并行而不是进程并行。这可以减少串行化和旋转池的一些开销。
  • 尝试使用pathos.pools._ProcessPool来更改pathos管理池的方式。没有下划线,pathos将池保持为单例,并且需要一个“终止”来显式地杀死池。使用下划线时,当删除池对象时,池将停止。请注意,您的caller函数没有closejoin (或terminate)池。
  • 您可能希望通过尝试并行处理的元素之一dill.dumps来检查序列化的程度。像大型numpy数组这样的东西可能需要一段时间才能序列化。如果传递的内容很大,您可以考虑使用共享内存数组(即multiprocess.Arraynumpy数组的等效版本--参见:numpy.ctypeslib)来最小化每个进程之间传递的内容。

后者是更多的工作,但如果您有大量的序列化,可以提供巨大的节省。没有共享内存池,因此如果需要执行该路由,则必须对单个multiprocess.Process对象执行for循环。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53468446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档