首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程python hdf5解析函数速度无提升

多线程python hdf5解析函数速度无提升
EN

Stack Overflow用户
提问于 2013-04-30 22:32:11
回答 2查看 519关注 0票数 1

我有一个函数:

1)将hdf5数据集读入为整数ascii代码

2)将ascii整数转换为characters...chr()函数

3)将字符连接到单个字符串函数中

在分析时,我发现大部分计算都花在了第2步上,即将ascii整数转换为字符。我通过使用以下命令对此调用进行了一定程度的优化:

代码语言:javascript
复制
''.join([chr(x) for x in file[dataSetName].value])

由于我的解析函数似乎受cpu限制(整数到字符的转换),而不是i/o限制,所以我希望随着用于解析的内核数量的增加,可以获得更多/更少的线性速度提升。串行解析一个文件需要大约15个seconds...to解析10个文件(在我的12核机器上)需要大约150秒,而使用10个线程。也就是说,似乎根本没有增强。

我使用以下代码来启动我的线程:

代码语言:javascript
复制
    threads=[]
    timer=[]
    threadNumber=10
    for i,d in enumerate(sortedDirSet):
        timer.append(time.time())
     #   self.loadFile(d,i)
        threads.append(Thread(target=self.loadFileargs=(d,i)))
        threads[-1].start()
        if(i%threadNumber==0):
            for i2,t in enumerate(threads):
                t.join()
                print(time.time()-timer[i2])
            timer=[]
            threads=[]

    for t in threads:
        t.join()

任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-30 22:35:09

Python不能使用多核(由于GIL),除非您派生子进程(例如,使用multiprocessing )。因此,你不会得到任何性能提升与繁衍线程的CPU限制的任务。

以下是使用multiprocessingqueue的脚本示例

代码语言:javascript
复制
from Queue import Empty # <-- only needed to catch Exception
from multiprocessing import Process, Queue, cpu_count

def loadFile(d, i, queue):
    # some other stuff
    queue.put(result)

if name == "main":
    queue = Queue()
    no = cpu_count()
    processes = []

    for i,d in enumerate(sortedDirSet):
        p = Process(target=self.loadFile, args=(d, i, queue))
        p.start()
        processes.append(p)

        if i % no == 0:
            for p in processes:
                p.join()
            processes = []

    for p in processes:
        p.join()

    results = []
    while True:
        try:
            # False means "don't wait when Empty, throw an exception instead"
            data = queue.get(False)
            results.append(data)
        except Empty:
            break

    # You have all the data, do something with it

另一种(更复杂的)方法是使用pipe而不是queue

生成进程,然后创建一个作业队列并(通过pipe)将它们发送给子进程(这样您就不必每次都创建一个进程),也会更有效率。但是这将会更加复杂,所以我们就让它这样吧。

票数 4
EN

Stack Overflow用户

发布于 2013-04-30 22:56:39

怪胎的答案是正确的,这将是GIL阻挠你的努力。

如果你要使用Python3,你可以用concurrent.futures很好地做到这一点。我相信PyPy也支持这个特性。

此外,你可以通过替换你的列表理解来提高代码的速度:

代码语言:javascript
复制
''.join([chr(x) for x in file[dataSetName].value])

使用地图:

代码语言:javascript
复制
''.join(map(chr, file[dataSetName].value))

我使用上述代码进行的测试(在大量随机列表上)显示,使用列表理解的时间为15.73秒,使用map的时间为12.44秒。

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

https://stackoverflow.com/questions/16302443

复制
相关文章

相似问题

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