进程或线程的性能改进

时间:2014-04-11 13:46:25

标签: python multithreading performance multiprocessing

我写了一个脚本,从我学校的网站上提取数据,而且我在执行时遇到了一些麻烦。

有20多个校区,每个校区都有三个学期的数据。该脚本查找这些学校名称,然后是每个学校可用的学期,然后是每个学期提供课程的科目/部门。然后脚本搜索每个部门的类,然后我用这些数据做事。

我在一个校园里定时执行脚本,它跑了三分多钟。当我为所有24个校区运行它花了一个多小时。我正在使用"请求"库,同步运行每个HTTP请求。我正在使用"请求"库,主要是因为它很好地处理会话。

通过让每个学期的各种请求并行运行,我正在寻找降低脚本运行时间的方法。我怀疑,如果我异步运行三个学期,那么每个学校应该花一分钟而不是三分钟。然后,我可以并行运行所有学校,并为所有数据实现相同的分钟。一分钟不到一个小时四分之一!

  1. 我猜错了,多线程/处理会大大缩短执行时间吗?我应该为线程或进程使用哪些Python库?

  2. 一旦我在一个主题上处理了每所学校,我该如何将所有学校的数据合并到一个地方?我知道线程改变全球状态的做法很糟糕,但这里的替代方案是什么?

3 个答案:

答案 0 :(得分:0)

1)你没错。对线程使用threading库。对于流程,您可以使用multiprocessingos.forksubprocess,具体取决于您希望如何使用它们。

2)谁说改变全球国家是一种糟糕的做法?这总是取决于背景。显然,你必须以某种方式在线程之间共享数据结构。但是,您不必使用全局变量。例如:

from threading import Thread

def my_task(id, holder, some_other_args):
    # do something
    holder[id] = my_result

def main():
    total_data = {}
    threads = []
    for i in range(100):
        t = Thread(target=my_task, args=(i, total_data, ...))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    print total_data  # <-- you have all results here

if __name__ == "__main__":
    main()

答案 1 :(得分:0)

在python中,你想要多线程多处理。由于GIL,线程在Python中表现不佳。

答案 2 :(得分:0)

为什么要使用全局变量?与奇特相同的代码,但没有传递给线程的全局变量:

#!/usr/bin/python3

import threading

class MyThread(threading.Thread):
    def __init__(self, target, name=None, args=(), kwargs={}):
        super().__init__(target=target, name=name, args=args, kwargs=kwargs)
        self.output = None
    def run(self):
        self.output = self._target(*self._args, **self._kwargs)


def my_task(i):
    # do something
    return 'response ' + str(i)

def main():
    total_data = list()
    threads = []
    for i in range(5):
        t = MyThread(target=my_task, args=[i,])
        t.start()
        threads.append(t)

    for t in threads:
        t.join()
        total_data.append(t.output)

    print(total_data)

if __name__ == "__main__":
    main()

输出是:

Jean@MyDesktop:~$ ./test_threads.py 
['response 0', 'response 1', 'response 2', 'response 3', 'response 4']

@yorodm:在这种情况下,我认为多线程应该足够了,除非在数据上进行繁重的处理。