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编程实现双击更新所有已安装python模块的方法
Jun 05 Python
python selenium 获取标签的属性值、内容、状态方法
Jun 22 Python
详解通过API管理或定制开发ECS实例
Sep 30 Python
python 不同方式读取文件速度不同的实例
Nov 09 Python
python 构造三维全零数组的方法
Nov 12 Python
在pycharm中使用git版本管理以及同步github的方法
Jan 16 Python
执行Django数据迁移时报 1091错误及解决方法
Oct 14 Python
使用pickle存储数据dump 和 load实例讲解
Dec 30 Python
python3 实现口罩抽签的功能
Mar 11 Python
Python-jenkins模块获取jobs的执行状态操作
May 12 Python
Python+Opencv实现把图片、视频互转的示例
Dec 17 Python
Python多个MP4合成视频的实现方法
Jul 16 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蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
CI框架给视图添加动态数据
2014/12/01 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
javascript字符串拼接的效率问题
2010/12/25 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
JavaScript基于setTimeout实现计数的方法
2015/05/08 Javascript
Bootstrap弹出带合法性检查的登录框实例代码【推荐】
2016/06/23 Javascript
js删除局部变量的实现方法
2016/06/25 Javascript
用v-html解决Vue.js渲染中html标签不被解析的问题
2016/12/14 Javascript
Angular2学习教程之ng中变更检测问题详解
2017/05/28 Javascript
打造通用的匀速运动框架(实例讲解)
2017/10/17 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
2018/08/07 Javascript
vue data引入本地图片的两种方式小结
2019/11/13 Javascript
JSONP 的原理、理解 与 实例分析
2020/05/16 Javascript
用js实现放大镜效果
2020/10/28 Javascript
Python编码时应该注意的几个情况
2013/03/04 Python
python list语法学习(带例子)
2013/11/01 Python
通过代码实例展示Python中列表生成式的用法
2015/03/31 Python
详解python单例模式与metaclass
2016/01/15 Python
Python多进程并发与多线程并发编程实例总结
2018/02/08 Python
python 中if else 语句的作用及示例代码
2018/03/05 Python
解决python升级引起的pip执行错误的问题
2018/06/12 Python
python处理“
2019/06/10 Python
python实现windows倒计时锁屏功能
2019/07/30 Python
python机器学习库xgboost的使用
2020/01/20 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
css3实现波纹特效、H5实现动态波浪效果
2018/01/31 HTML / CSS
英国领先的运动物理治疗供应公司:Vivomed
2018/07/14 全球购物
捷克移动配件网上商店:ProMobily.cz
2019/03/15 全球购物
高级文秘工作总结的自我评价
2013/09/28 职场文书
市场营销专业推荐信
2013/11/03 职场文书
会计学生自我鉴定
2014/02/06 职场文书
优秀员工自荐书
2015/03/06 职场文书
C站最全Python标准库总结,你想要的都在这里
2021/07/03 Python
Java中Quartz高可用定时任务快速入门
2022/04/03 Java/Android
python+pytest接口自动化之token关联登录的实现
2022/04/06 Python