转自:http://www.redicecn.com/html/Python/20111223/355.html

Python发挥不了多核处理器的性能(据说是受限于GIL,被锁住只能用一个CPU核心,关于这个,这里有篇文章),但是可以通过Python的multiprocessing(多进程)模块或者并行运算模块(例如,pprocess)来使用到多核。

测试代码如下,程序先后分别测试了串行运算、并行运算以及多线程和多进程执行同一个函数所花费的时间。

  1. #! /usr/local/bin/python2.7
  2. # test.py
  3. import time
  4. import pprocess # 该模块只能在linux下使用
  5. import threading
  6. from multiprocessing import Process
  7. def takeuptime(n):
  8. chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
  9. s = chars * 1000
  10. for i in range(10*n):
  11. for c in chars:
  12. s.count(c)
  13. if __name__ == '__main__':
  14. list_of_args = [1000, 1000, 1000, 1000]
  15. # Serial computation
  16. start = time.time()
  17. serial_results = [takeuptime(args) for args in list_of_args]
  18. print "%f s for traditional, serial computation." % (time.time() - start)
  19. # Parallel computation
  20. nproc = 4 # maximum number of simultaneous processes desired
  21. results = pprocess.Map(limit=nproc, reuse=1)
  22. parallel_function = results.manage(pprocess.MakeReusable(takeuptime))
  23. start = time.time()
  24. # Start computing things
  25. for args in list_of_args:
  26. parallel_function(args)
  27. parallel_results = results[:]
  28. print "%f s for parallel computation." % (time.time() - start)
  29. # Multithreading computation
  30. nthead = 4 # number of threads
  31. threads = [threading.Thread(target=takeuptime, args=(list_of_args[i],)) for i in range(nthead)]
  32. start = time.time()
  33. # Start threads one by one
  34. for thread in threads:
  35. thread.start()
  36. # Wait for all threads to finish
  37. for thread in threads:
  38. thread.join()
  39. print "%f s for multithreading computation." % (time.time() - start)
  40. # Multiprocessing computation
  41. process = []
  42. nprocess = 4 # number of processes
  43. for i in range(nprocess):
  44. process.append(Process(target=takeuptime, args=(list_of_args[i],)))
  45. start = time.time()
  46. # Start processes one by one
  47. for p in process:
  48. p.start()
  49. # Wait for all processed to finish
  50. for i in process:
  51. p.join()
  52. print "%f s for multiprocessing computation." % (time.time() - start)

运行结果如下:

[root@localhost test]# python test.py

62.452934 s for traditional, serial computation.

20.665276 s for parallel computation.

64.835923 s for multithreading computation.

18.392281 s for multiprocessing computation.

从测试结果可以明显看出并行运算和多进程计算速度明显要快于串行计算和多线程计算。

这里有个问题,为什么多线程的所花的时间不比串行单线程的少呢(64.873760 > 62.452934)?

根据我们的常规经验,多线程肯定要比单线程要快,为什么测试结果却不是这样呢?

前面已经提到了,Python只能用到一个CPU核心,因此即便是多线程,在同一时间CPU也只能处理一个线程运算,多个线程并不能并行的运行,他们是轮流切换执行的。

因此,只有当线程中会出现阻塞时,多线程才有意义,比如线程中有数据下载,在等待数据返回时线程阻塞了,此时CPU就可以来处理其它线程的运算。

上面测试程序中的takeuptime()函数没有阻塞,它不停地在进行着运算,所以多线程和单线程的效果是一样的(线程切换也会花费时间,所以此时多线程花费的时候甚至比单线程多一些)。

并行运算和多进程运算之所以快,就是因为他们能同时利用多个CPU核心,多个数据运算能同时进行。

我们把takeuptime()函数改成有阻塞的,再测试一下:

  1. def takeuptime(n):
  2. def download(url):
  3. # simulate downloading
  4. time.sleep(2)
  5. for i in range(5):
  6. html = download('http://www.redicecn.com/page%d.html' % i)

新的运行结果如下:

[root@localhost test]# python test.py

39.996438 s for traditional, serial computation.

10.003863 s for parallel computation.

10.003480 s for multithreading computation.

10.008936 s for multiprocessing computation.

可以看到在有阻塞的数据处理过程中,多线程的作用还是很明显的。

感谢Richard, 和老吴。

Python串行运算、并行运算、多线程、多进程对比实验的更多相关文章

  1. python学习之多线程多进程

    python基础 进程&线程 进程是一组资源的集合,运行一个系统就是打开了一个进程,如果同时打开了两个记事本就是开启了两个进程,进程是一个笼统的概念,进程中由线程干活工作,由进程统一管理 一个 ...

  2. 011_Python中单线程、多线程和多进程的效率对比实验

    Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread)的情况下,不能发挥多核的优势.而使用多进程(Multiprocess),则可以发挥多 ...

  3. python之路-----多线程与多进程

    一.进程和线程的概念 1.进程(最小的资源单位): 进程:就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成. 程序:我们编写的程序用来描述进程要完成哪些功能以 ...

  4. Python有了asyncio和aiohttp在爬虫这类型IO任务中多线程/多进程还有存在的必要吗?

    最近正在学习Python中的异步编程,看了一些博客后做了一些小测验:对比asyncio+aiohttp的爬虫和asyncio+aiohttp+concurrent.futures(线程池/进程池)在效 ...

  5. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  6. Python系列之多线程、多进程

    线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程. Python的标准库提供 ...

  7. 为什么在Python里推荐使用多进程而不是多线程

    转载  http://bbs.51cto.com/thread-1349105-1.html 最近在看Python的多线程,经常我们会听到老手说:"Python下多线程是鸡肋,推荐使用多进程 ...

  8. 为什么在Python里推荐使用多进程而不是多线程?

    最近在看Python的多线程,经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢?   要知其然,更要知其所以然.所以有了下面的深入研究: 首先强调背景: 1. ...

  9. 为什么在Python里推荐使用多进程而不是多线程?(为什么python多线程无法增加CPU使用率?)

    最近在看Python的多线程,经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢? 要知其然,更要知其所以然.所以有了下面的深入研究: 首先强调背景:     ...

随机推荐

  1. YAR 并行RPC框架研究

    前几天,部门召开了PHP技术峰会 学习会议,大家分别对这次会议的PPT 做了简单的介绍, 其中提到了 鸟哥[惠新辰]的一篇PPT<微博LAMP 演变>,如果谁有需要可以去谷歌搜,或者去 h ...

  2. Maven学习小结(七 生命周期[转])

    Maven2的阶段(生命周期)说明:Maven2拥有三套独立的生命周期,Maven的命令也是基于这些生命周期来说的.1.clean:清理先前构建的构件,又分为下面三个下阶段: a.pre-clean ...

  3. hello world of hibernate Annotation

    1:建立所需要的类,如: package com.hibernate.model; import javax.persistence.Entity; import javax.persistence. ...

  4. 在vs中跑动kdtree 和 bbf

    这两天的学习模型都来自:http://blog.csdn.net/masibuaa/article/details/9246493 所谓的bbf 英文名字叫做best bin first 译名:最优节 ...

  5. sql 联合查询速度慢,需要对其进行分组

    分组:SELECT   * FROM(SELECT ROW_NUMBER() OVER(ORDER BY  ProjID) as row_number,* FROM ( select ProjAppl ...

  6. ES 父子文档查询

    父子文档的特点 1. 父/子文档是完全独立的. 2. 父文档更新不会影响子文档. 3. 子文档更新不会影响父文档或者其它子文档. 父子文档的映射与索引 1. 父子关系 type 的建立必须在索引新建或 ...

  7. Angular 2.0 从0到1:Rx--隐藏在Angular 2.x中利剑

    第一节:Angular 2.0 从0到1 (一)第二节:Angular 2.0 从0到1 (二)第三节:Angular 2.0 从0到1 (三)第四节:Angular 2.0 从0到1 (四)第五节: ...

  8. 【转】移动互联网应用测试成长技能树V1.0

  9. Ehcache(2.9.x) - API Developer Guide, Cache Event Listeners

    About Cache Event Listeners Cache listeners allow implementers to register callback methods that wil ...

  10. Asp.net中基于Forms验证的角色验证授权

    Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活. Forms 验证方式对基于用户的验证授 ...