进程或线程的性能改进

2024-07-04 10:52:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个脚本,从我学校的网站上提取数据,我在执行时间上遇到了一些问题。你知道吗

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

我只在一个校园里对脚本的执行进行了计时,它运行了三分钟多。当我在所有24个校区运行它时,它花了一个多小时。我使用的是“requests”库,它同步运行每个HTTP请求。我使用“requests”库,主要是因为它可以很好地处理会话。你知道吗

我正在寻找方法来减少脚本运行所需的时间,方法是让每个学期的各种请求并行运行。我怀疑如果我异步运行三个学期,那么每个学校应该花一分钟,而不是三分钟。然后,我可以并行运行所有学校,并为所有数据实现同一分钟。一分钟比一小时零一刻少得多!你知道吗

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

  2. 一旦我在一个线程上处理了每个学校,如何将所有学校的数据合并到一个地方?我知道线程改变全局状态被认为是不好的做法,但是这里有什么替代方法呢?


Tags: 数据方法脚本网站时间requests线程学校
3条回答

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

#!/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:在这种情况下,我认为多线程应该足够了,除非在本地对数据进行繁重的处理。你知道吗

在python中,您需要多线程上的多处理。线程在Python中表现不好是因为GIL。你知道吗

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()

相关问题 更多 >

    热门问题