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设计足球联赛赛程表程序的思路与简单实现示例
Jun 28 Python
深入浅出学习python装饰器
Sep 29 Python
python编程羊车门问题代码示例
Oct 25 Python
python使用TensorFlow进行图像处理的方法
Feb 28 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
使用Python的SymPy库解决数学运算问题的方法
Mar 27 Python
windows10下安装TensorFlow Object Detection API的步骤
Jun 13 Python
PyQt5笔记之弹出窗口大全
Jun 20 Python
详解python实现交叉验证法与留出法
Jul 11 Python
django rest framework 自定义返回方式
Jul 12 Python
Selenium及python实现滚动操作多种方法
Jul 21 Python
OpenCV-Python实现图像平滑处理操作
Jun 08 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数组函数序列之sort() 对数组的元素值进行升序排序
2011/11/02 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
关于文本框的一些限制控制总结~~
2010/04/15 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
JS定义网页表单提交(submit)的方法
2015/03/20 Javascript
JS实现点击上移下移LI行数据的方法
2015/08/05 Javascript
Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)
2016/06/21 Javascript
js实现为a标签添加事件的方法(使用闭包循环)
2016/08/02 Javascript
Vue.js实现简单动态数据处理
2017/02/13 Javascript
原生js实现旋转木马轮播图效果
2017/02/27 Javascript
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
详解webpack和webpack-simple中如何引入css文件
2017/06/28 Javascript
VUE前端cookie简单操作
2017/10/17 Javascript
JS脚本加载后执行相应回调函数的操作方法
2018/02/28 Javascript
对vuejs的v-for遍历、v-bind动态改变值、v-if进行判断的实例讲解
2018/08/27 Javascript
layui点击数据表格添加或删除一行的例子
2019/09/12 Javascript
vue实现购物车功能(商品分类)
2020/04/20 Javascript
原生JS实现音乐播放器的示例代码
2021/02/25 Javascript
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
python多线程案例之多任务copy文件完整实例
2019/10/29 Python
python删除指定列或多列单个或多个内容实例
2020/06/28 Python
python程序实现BTC(比特币)挖矿的完整代码
2021/01/20 Python
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
管理心得体会
2013/12/28 职场文书
个人职业生涯规划书1500字
2013/12/31 职场文书
乡镇挂职心得体会
2014/09/04 职场文书
2014年职称评定工作总结
2014/11/26 职场文书
初级职称评定工作总结
2015/08/13 职场文书
七年级思品教学反思
2016/02/20 职场文书
不知如何爱孩子,这些方法教会您
2019/08/06 职场文书
Golang二维数组的使用方式
2021/05/28 Golang
python异步的ASGI与Fast Api实现
2021/07/16 Python
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL
HDFS免重启挂载新磁盘
2022/04/06 Servers