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 解析XML python模块xml.dom解析xml实例代码
Feb 07 Python
python实现ip查询示例
Mar 26 Python
Python模拟登陆实现代码
Jun 14 Python
详解Golang 与python中的字符串反转
Jul 21 Python
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
解决pycharm无法识别本地site-packages的问题
Oct 13 Python
Python实现带参数的用户验证功能装饰器示例
Dec 14 Python
python实现人工智能Ai抠图功能
Sep 05 Python
django 简单实现登录验证给你
Nov 06 Python
python 实现二维列表转置
Dec 02 Python
使用sklearn对多分类的每个类别进行指标评价操作
Jun 11 Python
python 机器学习的标准化、归一化、正则化、离散化和白化
Apr 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 fckeditor 调用的函数
2009/06/21 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
php中用memcached实现页面防刷新功能
2014/08/19 PHP
php遍历解析xml字符串的方法
2016/05/05 PHP
php-fpm重启导致的程序执行中断问题详解
2019/04/29 PHP
Javascript 继承实现例子
2009/08/12 Javascript
javascript 简练的几个函数
2009/08/29 Javascript
JQuery AJAX 中文乱码问题解决
2013/06/05 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
2016/01/26 Javascript
微信小程序 css使用技巧总结
2017/01/09 Javascript
关于vue-resource报错450的解决方案
2017/07/24 Javascript
javascript 开发之网页兼容各种浏览器
2017/09/28 Javascript
微信小程序使用modal组件弹出对话框功能示例
2017/11/29 Javascript
JavaScript比较同一天的时间大小实例代码
2018/02/09 Javascript
Vue实现搜索 和新闻列表功能简单范例
2018/03/16 Javascript
浅谈Angular7 项目开发总结
2018/12/19 Javascript
vue获取时间戳转换为日期格式代码实例
2019/04/17 Javascript
JS实现处理时间,年月日,星期的公共方法示例
2019/05/31 Javascript
ES6模板字符串和标签模板的应用实例分析
2019/06/25 Javascript
vue 组件销毁并重置的实现
2020/01/13 Javascript
Vue实现随机验证码功能
2020/12/29 Vue.js
[55:42]VG vs VGJ.T 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
Python 安装setuptools和pip工具操作方法(必看)
2017/05/22 Python
python+VTK环境搭建及第一个简单程序代码
2017/12/13 Python
opencv python 图像去噪的实现方法
2018/08/31 Python
python树莓派红外反射传感器
2019/01/21 Python
通过 Django Pagination 实现简单分页功能
2019/11/11 Python
Python解释器及PyCharm工具安装过程
2020/02/26 Python
Python实现汇率转换操作
2020/05/03 Python
html5响应式开发自动计算fontSize的方法
2020/01/13 HTML / CSS
信用卡结清证明怎么写
2014/09/13 职场文书
党员对照检查材料思想汇报
2014/09/16 职场文书
教师自查自纠材料
2014/10/14 职场文书
2014年教务工作总结
2014/12/03 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
自定义函数实现单词排序并运用于PostgreSQL(实现代码)
2021/04/22 PostgreSQL