Python3如何使用多线程升程序运行速度


Posted in Python onAugust 11, 2020

优化前后新老代码如下:

from git_tools.git_tool import get_collect_projects, QQNews_Git
from threading import Thread, Lock
import datetime

base_url = "http://git.xx.com"
project_members_commits_lang_info = {}
lock = Lock()
threads = []

'''
Author:zenkilan
'''


def count_time(func):
  def took_up_time(*args, **kwargs):
    start_time = datetime.datetime.now()
    ret = func(*args, **kwargs)
    end_time = datetime.datetime.now()
    took_up_time = (end_time - start_time).total_seconds()
    print(f"{func.__name__} execution took up time:{took_up_time}")
    return ret

  return took_up_time


def get_project_member_lang_code_lines(git, member, begin_date, end_date):
  global project_members_commits_lang_info
  global lock
  member_name = member["username"]
  r = git.get_user_info(member_name)
  if not r["id"]:
    return
  user_commits_lang_info = git.get_commits_user_lang_diff_between(r["id"], begin_date, end_date)
  if len(user_commits_lang_info) == 0:
    return
  lock.acquire()
  project_members_commits_lang_info.setdefault(git.project, dict())
  project_members_commits_lang_info[git.project][member_name] = user_commits_lang_info
  lock.release()


def get_project_lang_code_lines(project, begin_date, end_date):
  global threads
  git = QQNews_Git(project[1], base_url, project[0])
  project_members = git.get_project_members()
  if len(project_members) == 0:
    return
  for member in project_members:
    thread = Thread(target=get_project_member_lang_code_lines, args=(git, member, begin_date, end_date))
    threads.append(thread)
    thread.start()


@count_time
def get_projects_lang_code_lines(begin_date, end_date):
  """
  获取项目代码行语言相关统计——新方法(提升效率)
  应用多线程替代for循环
  并发访问共享外部资源
  :return:
  """
  global project_members_commits_lang_info
  global threads
  for project in get_collect_projects():
    thread = Thread(target=get_project_lang_code_lines, args=(project, begin_date, end_date))
    threads.append(thread)
    thread.start()


@count_time
def get_projects_lang_code_lines_old(begin_date, end_date):
  """
  获取项目代码行语言相关统计——老方法(耗时严重)
  使用最基本的思路进行编程
  双层for循环嵌套并且每层都包含耗时操作
  :return:
  """
  project_members_commits_lang_info = {}
  for project in get_collect_projects():
    git = QQNews_Git(project[1], base_url, project[0])
    project_members = git.get_project_members()
    user_commits_lang_info_dict = {}
    if len(project_members) == 0:
      continue
    for member in project_members:
      member_name = member["username"]
      r = git.get_user_info(member_name, debug=False)
      if not r["id"]:
        continue
      try:
        user_commits_lang_info = git.get_commits_user_lang_diff_between(r["id"], begin_date, end_date)
        if len(user_commits_lang_info) == 0:
          continue
        user_commits_lang_info_dict[member_name] = user_commits_lang_info
        project_members_commits_lang_info[git.project] = user_commits_lang_info_dict
      except:
        pass
  return project_members_commits_lang_info


def test_results_equal(resultA, resultB):
  """
  测试方法
  :param resultA:
  :param resultB:
  :return:
  """
  print(resultA)
  print(resultB)
  assert len(str(resultA)) == len(str(resultB))


if __name__ == '__main__':
  from git_tools.config import begin_date, end_date

  get_projects_lang_code_lines(begin_date, end_date)
  for t in threads:
    t.join()
  old_result = get_projects_lang_code_lines_old(begin_date, end_date)
  test_results_equal(old_result, project_members_commits_lang_info)

老方法里外层for循环和内层for循环里均存在耗时操作:

1)git.get_project_members()

2)git.get_user_info(member_name, debug=False)

分两步来优化,先里后外或先外后里都行。用多线程替换for循环,并发共享外部资源,加锁避免写冲突。

测试结果通过,函数运行时间装饰器显示(单位秒):

get_projects_lang_code_lines execution took up time:1.85294

get_projects_lang_code_lines_old execution took up time:108.604177

速度提升了约58倍

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
一个检测OpenSSL心脏出血漏洞的Python脚本分享
Apr 10 Python
Python自动化测试工具Splinter简介和使用实例
May 13 Python
深入讲解Python中面向对象编程的相关知识
May 25 Python
Python实现Linux中的du命令
Jun 12 Python
Python Nose框架编写测试用例方法
Oct 26 Python
对Python信号处理模块signal详解
Jan 09 Python
Django自定义用户表+自定义admin后台中的字段实例
Nov 18 Python
Python连接SQLite数据库并进行增册改查操作方法详解
Feb 18 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
Feb 26 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
Mar 13 Python
Python基于BeautifulSoup爬取京东商品信息
Jun 01 Python
为什么说python更适合树莓派编程
Jul 20 Python
使用Python pip怎么升级pip
Aug 11 #Python
python中通过pip安装库文件时出现“EnvironmentError: [WinError 5] 拒绝访问”的问题及解决方案
Aug 11 #Python
Python 代码调试技巧示例代码
Aug 11 #Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
Aug 11 #Python
Python函数递归调用实现原理实例解析
Aug 11 #Python
零基础学python应该从哪里入手
Aug 11 #Python
Python如何测试stdout输出
Aug 10 #Python
You might like
PHP生成图片验证码、点击切换实例
2014/06/25 PHP
php获取指定范围内最接近数的方法
2015/06/02 PHP
Zend Framework校验器Zend_Validate用法详解
2016/12/09 PHP
PHP 代码简洁之道(小结)
2019/10/16 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
数组Array进行原型prototype扩展后带来的for in遍历问题
2010/02/07 Javascript
js中 关于undefined和null的区别介绍
2013/04/16 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
2013/04/18 Javascript
制作jquery遮罩层效果导航菜单代码分享
2013/12/25 Javascript
15款最好的Bootstrap在线编辑器
2016/08/03 Javascript
AngularJS的ng-repeat指令与scope继承关系实例详解
2017/01/21 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
Vue分页组件实例代码
2017/04/17 Javascript
jQuery常见面试题之DOM操作详析
2017/07/05 jQuery
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
Vue两种组件类型:递归组件和动态组件的用法
2020/08/06 Javascript
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
python编码总结(编码类型、格式、转码)
2016/07/01 Python
Python实现通讯录功能
2018/02/22 Python
django2用iframe标签完成网页内嵌播放b站视频功能
2018/06/20 Python
Django + Uwsgi + Nginx 实现生产环境部署的方法
2018/06/20 Python
python中从str中提取元素到list以及将list转换为str的方法
2018/06/26 Python
python 自定义对象的打印方法
2019/01/12 Python
python实现转圈打印矩阵
2019/03/02 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
线程安全及Python中的GIL原理分析
2019/10/29 Python
Python字符串三种格式化输出
2020/09/17 Python
使用Python封装excel操作指南
2021/01/29 Python
秋季运动会通讯稿
2014/01/24 职场文书
高中地理教学反思
2014/01/29 职场文书
投标承诺书怎么写
2014/05/24 职场文书
工厂门卫的岗位职责
2014/07/27 职场文书
2014年社区居委会主任重阳节讲话稿
2014/09/25 职场文书
检讨书范文
2015/01/27 职场文书
2015年教师教学工作总结
2015/04/28 职场文书