Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 线程化以快速创建大量图表_Python_Multithreading_Optimization_Matplotlib - Fatal编程技术网

Python 线程化以快速创建大量图表

Python 线程化以快速创建大量图表,python,multithreading,optimization,matplotlib,Python,Multithreading,Optimization,Matplotlib,我一直在试图找到让以下代码执行得更快的方法: def do_chart(target="IMG_BACK", xlabel="xlabel", ylabel="ylabel", title="title", ydata=pylab.arange(1961, 2031, 1)): global MYRAMDICT MYRAMDICT = {} print "here" for i in range(70): MYRAMDICT[i] =

我一直在试图找到让以下代码执行得更快的方法:

def do_chart(target="IMG_BACK", xlabel="xlabel", ylabel="ylabel", title="title",       ydata=pylab.arange(1961, 2031, 1)):
    global MYRAMDICT
    MYRAMDICT = {}
    print "here"
    for i in range(70):
        MYRAMDICT[i] = cStringIO.StringIO()
        xdata = pylab.arange(1961, 2031, 1)
        pylab.figure(num=None, figsize=(10.24, 5.12), dpi=1, facecolor='w', edgecolor='k')
        pylab.plot(xdata, ydata, linewidth=3.0)
        pylab.xlabel(xlabel); pylab.ylabel(ylabel); pylab.title(i)
        pylab.grid(True)
        pylab.savefig(MYRAMDICT[i], format='png')
        pylab.close()
这个函数(请忽略pylab命令,它们在这里只是为了说明)创建了一个字典(MYTAMDICT),我用cString对象填充了它,用于在memmory上存储图表。这些图表稍后会动态呈现给用户


有人能帮我利用线程,这样我就可以使用我所有的内核,使这个功能执行得更快吗?或者告诉我一些改进的想法?

如果且仅当pylab在执行时释放gil时,线程将帮助您。
此外,pylib必须是线程安全的,并且您的代码必须以线程安全的方式使用它,而这种情况可能并不总是如此

也就是说,如果要使用线程,我认为这是作业队列的经典案例;因此,我会使用一个,足够好的来处理这个模式

这里有一个示例,我只是通过干预您的代码和队列文档中给出的示例而给出。我甚至没有彻底检查它,所以它会有bug;与其说是给出一个想法,不如说是给出一个想法

# "Business" code
def do_chart(target="IMG_BACK", xlabel="xlabel", ylabel="ylabel", title="title",       ydata=pylab.arange(1961, 2031, 1)):
    global MYRAMDICT
    MYRAMDICT = {}
    print "here"
    for i in range(70):
      q.put(i)
    q.join()       # block until all tasks are done

def do_work(i):
    MYRAMDICT[i] = cStringIO.StringIO()
    xdata = pylab.arange(1961, 2031, 1)
    pylab.figure(num=None, figsize=(10.24, 5.12), dpi=1, facecolor='w', edgecolor='k')
    pylab.plot(xdata, ydata, linewidth=3.0)
    pylab.xlabel(xlabel); pylab.ylabel(ylabel); pylab.title(i)
    pylab.grid(True)
    pylab.savefig(MYRAMDICT[i], format='png')
    pylab.close()


# Handling the queue
def worker():
    while True:
        i = q.get()
        do_work(i)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

根据描述,使用多处理比使用线程要好得多。。。您有一个“令人尴尬的并行”问题,并且没有磁盘IO约束(您正在写入内存)。当然,在进程之间来回传递大型内容会很昂贵,但是返回表示.png的字符串应该不会太糟糕

这可以很简单地做到:

import multiprocessing
import cStringIO

import matplotlib.pyplot as plt
import numpy as np

import itertools

def main():
    """Generates 1000 random plots and saves them as .png's in RAM"""
    pool = multiprocessing.Pool()
    same_title = itertools.repeat('Plot %i')
    fig_files = pool.map(plot, itertools.izip(xrange(1000), same_title))

def plot(args):
    """Make a random plot"""
    # Unfortunately, pool.map (and imap) only support a single argument to
    # the function, so you'll have to unpack a tuple of arguments...
    i, titlestring = args

    outfile = cStringIO.StringIO()

    x = np.cumsum(np.random.random(100) - 0.5)

    fig = plt.figure()
    plt.plot(x)
    fig.savefig(outfile, format='png', bbox_inches='tight')
    plt.title(titlestring % i)
    plt.close()

    # cStringIO files aren't pickelable, so we'll return the string instead...
    outfile.seek(0)
    return outfile.read()

main()
如果不使用多处理,在我的机器上大约需要250秒。对于多处理(8核),需要约40秒


希望这有点帮助……

当前的性能是什么?它需要快多少?#史蒂文:如果我在for循环的开头插入一个“print I”,我可以看到每张图像需要将近1秒的时间。但是当我有了我应该使用的真正的pylab代码时,这个时间会增加。此函数将在用户每次更改新数据库时运行,因此它会经常更改。我知道我可以只画第一张图片,而另一张是在背景中完成的,但我觉得线程化听起来是最好的解决方案。这很酷。谢谢你的帮助。但我有个问题要问你。我为Python2.4安装了一个多处理的后端口,但是当我使用你的代码时,我得到了:***************************************************************************************************************************************加载-c*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************?IOError:[Errno 2]没有这样的文件或目录:'-c'**加载时间:0.00秒**警告:脚本中有错误,请按任意键退出?非常感谢你的帮助。@relima-Huh。。。我猜这是2.4上的多处理的问题。。。无论如何,在2.6和2.7上,一切似乎都很顺利。。。恐怕我没有比这更好的主意了,不过。。。