加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

想提高计算速度?作为数据科学家你应该知道这些Python多线程、进程知识

发布时间:2019-09-19 12:32:25 所属栏目:建站 来源:skura
导读:每个数据科学项目迟早都会面临一个不可避免的挑战:速度问题。使用更大的数据集会导致处理速度变慢,因此最终必须想办法优化算法的运行时间。正如你们大多数人已经知道的,并行化是这种优化的必要步骤。python 为并行化提供了两个内置库:多处理和线程。在

GUI 程序始终使用线程来使应用程序响应。例如,在文本编辑程序中,一个线程负责记录用户输入,另一个线程负责显示文本,第三个线程负责拼写检查,等等。在这里,程序必须等待用户交互,这是最大的瓶颈。使用多处理不会使程序更快。

线程的另一个用例是 io 绑定或网络绑定的程序,例如 web-scrapers。在这种情况下,多个线程可以同时处理多个网页的刮擦。线程必须从 Internet 下载网页,这将是最大的瓶颈,因此线程是一个完美的解决方案。Web 服务器是受网络约束的,工作原理与此类似;有了它们,多处理就没有线程的优势了。另一个相关的例子是 tensorflow,它使用线程池并行地转换数据。

多处理的使用案例

如果程序是 CPU 密集型的,并且不需要进行任何 IO 或用户交互,那么多处理就比线程更加突出。例如,任何一个只处理数字的程序都可以使用多处理得到极大的加速;事实上,线程可能会减慢它的速度。一个有趣的实际例子是 Pytorch Dataloader,它使用多个子进程将数据加载到 GPU 中。

python 中的并行化

python 为同名的并行化方法提供了两个库——多处理和线程。尽管它们之间有着根本的区别,但这两个库提供了非常相似的 API(从 python 3.7 开始)。让我们来具体看看吧。

  1. import threading  
  2. import random  
  3. from functools import reduce  
  4.  
  5. def func(number): 
  6.    random_list = random.sample(range(1000000), number) 
  7.    return reduce(lambda x, y: x*y, random_list)  
  8. number = 50000  
  9. thread1 = threading.Thread(target=func, args=(number,))  
  10. thread2 = threading.Thread(target=func, args=(number,))  
  11.  
  12. thread1.start()  
  13. thread2.start()  
  14.  
  15. thread1.join()  
  16. thread2.join() 

你可以看到,我创建了一个函数 func,它创建一个随机数列表,然后按顺序将其所有元素相乘。如果物品数量足够大,比如说 5 万或 10 万件,这可能是一个相当繁重的过程。

然后,我创建了两个线程来执行同一个函数。线程对象有一个异步启动线程的 start 方法。如果我们想等待它们终止并返回,我们必须调用 join 方法,这就是我们在上面所做的。

如你所见,在后台将新线程转到任务的 API 非常简单。最棒的是,用于多处理的 API 也几乎完全相同;让我们来检查一下吧~

  1. import multiprocessing  
  2. import randomfrom functools  
  3. import reduce  
  4.  
  5. def func(number): 
  6.    random_list = random.sample(range(1000000), number) 
  7.    return reduce(lambda x, y: x*y, random_list) 
  8.  
  9. number = 50000  
  10. process1 = multiprocessing.Process(target=func, args=(number,)) 
  11. process2 = multiprocessing.Process(target=func, args=(number,))  
  12.  
  13. process1.start()  
  14. process2.start()  
  15.  
  16. process1.join()  
  17. process2.join() 

在这里它只是交换线程。有着多处理的线程。

显然,你可以用它做很多事情,但这不在本文的范围内,所以我们不在这里讨论。如果你有兴趣了解更多信息,请查看这里和这里的文档:https://docs.python.org/3/library/threading.html 和 https://docs.python.org/3/library/threading.html 。

基准点

现在我们已经了解了实现并行化的代码是什么样子的,让我们回到性能问题上来。如前所述,线程不适合用于 CPU 限制的任务;在这些情况下,它最终成为一个瓶颈。我们可以使用一些简单的基准来验证这一点。

首先,让我们看看在我上面展示的代码示例中,线程处理与多处理是如何比较的。请记住,此任务不涉及任何类型的 IO,因此它是纯 CPU 绑定的任务。

想提高计算速度?作为数据科学家你应该知道这些Python多线程、进程知识

让我们看看一个 IO 绑定任务的类似基准。例如,以下函数:

  1. import requestsdef func(number): 
  2.    url = 'http://example.com/' 
  3.    for i in range(number): 
  4.        response = requests.get(url) 
  5.        with open('example.com.txt', 'w') as output: 
  6.            output.write(response.text) 

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读