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 相关文章推荐
python利用装饰器进行运算的实例分析
Aug 04 Python
Python的collections模块中的OrderedDict有序字典
Jul 07 Python
使用Python将数组的元素导出到变量中(unpacking)
Oct 27 Python
python字符串str和字节数组相互转化方法
Mar 18 Python
python编程培训 python培训靠谱吗
Jan 17 Python
Django中针对基于类的视图添加csrf_exempt实例代码
Feb 11 Python
使用Python轻松完成垃圾分类(基于图像识别)
Jul 09 Python
python实现对变位词的判断方法
Apr 05 Python
Django 解决model 反向引用中的related_name问题
May 19 Python
python3读取autocad图形文件.py实例
Jun 05 Python
python3实现简单飞机大战
Nov 29 Python
pandas中对文本类型数据的处理小结
Nov 01 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(一)
2012/03/21 PHP
php上传文件并显示上传进度的方法
2015/03/24 PHP
基于Laravel5.4实现多字段登录功能方法示例
2017/08/11 PHP
PHP实现的回溯算法示例
2017/08/15 PHP
Django中的cookie与session操作实例代码
2017/08/17 PHP
php操作mongodb封装类与用法实例
2018/09/01 PHP
ie 调试javascript的工具
2009/04/29 Javascript
javascript 保存文件到本地实现方法
2012/11/29 Javascript
基于nodejs+express(4.x+)实现文件上传功能
2015/11/23 NodeJs
JavaScript基于原型链的继承
2016/06/22 Javascript
实例解析Array和String方法
2016/12/14 Javascript
AngularJS中的按需加载ocLazyLoad示例
2017/01/11 Javascript
angularJS模态框$modal实例代码
2017/05/27 Javascript
JS手机端touch事件计算滑动距离的方法示例
2017/10/26 Javascript
js删除数组中的元素delete和splice的区别详解
2018/02/03 Javascript
基于vue2.0动态组件及render详解
2018/03/17 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
2018/09/13 Javascript
微信小程序点餐系统开发常见问题汇总
2019/08/06 Javascript
vue输入节流,避免实时请求接口的实例代码
2019/10/30 Javascript
nodejs实现UDP组播示例方法
2019/11/04 NodeJs
使用Promise封装小程序wx.request的实现方法
2019/11/13 Javascript
javascript自定义右键菜单插件
2019/12/16 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
[51:20]完美世界DOTA2联赛PWL S2 Magma vs PXG 第一场 11.28
2020/12/01 DOTA
python实现基于信息增益的决策树归纳
2018/12/18 Python
pycharm创建scrapy项目教程及遇到的坑解析
2019/08/15 Python
如何基于pythonnet调用halcon脚本
2020/01/20 Python
防汛工作情况汇报
2014/10/28 职场文书
公司承诺函范文
2015/01/21 职场文书
西岭雪山导游词
2015/02/06 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
房地产销售助理岗位职责
2015/04/14 职场文书
继续教育心得体会(共6篇)
2016/01/19 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书
pycharm debug 断点调试心得分享
2021/04/16 Python
详细了解MVC+proxy
2021/07/09 Java/Android