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 相关文章推荐
通过C++学习Python
Jan 20 Python
Python下rrdtool模块的基本使用方法
Nov 13 Python
详解Python 数据库 (sqlite3)应用
Dec 07 Python
python线程中同步锁详解
Apr 27 Python
python多线程共享变量的使用和效率方法
Jul 16 Python
pd.DataFrame统计各列数值多少的实例
Dec 05 Python
Python二次规划和线性规划使用实例
Dec 09 Python
Win下PyInstaller 安装和使用教程
Dec 25 Python
如何基于Python创建目录文件夹
Dec 31 Python
Python中的Cookie模块如何使用
Jun 04 Python
详解利用python识别图片中的条码(pyzbar)及条码图片矫正和增强
Nov 17 Python
python 爬虫请求模块requests详解
Dec 04 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
初学者入门:细述PHP4的核心Zend
2006/09/05 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
2015/12/17 PHP
phpmyadmin下载、安装、配置教程
2017/05/16 PHP
php魔法函数与魔法常量使用介绍
2017/07/23 PHP
实例讲解php实现多线程
2019/01/27 PHP
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
面向对象Javascript核心支持代码分享
2012/05/23 Javascript
Extjs单独定义各组件的实例代码
2013/06/25 Javascript
JavaScript中的eval()函数详解
2013/08/22 Javascript
JS中操作JSON总结
2020/12/06 Javascript
jquery左边浮动到一定位置时显示返回顶部按钮
2014/06/05 Javascript
asp知识整理笔记3(问答模式)
2015/09/27 Javascript
JS判断元素是否在数组内的实现代码
2016/03/30 Javascript
分享javascript实现的冒泡排序代码并优化
2016/06/05 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
layui-table获得当前行的上/下一行数据的例子
2019/09/24 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
2019/10/11 Javascript
es6函数之严格模式用法实例分析
2020/03/17 Javascript
JavaScript实现移动端拖动元素
2020/11/24 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
JS闭包原理及其使用场景解析
2020/12/03 Javascript
[02:46]解说DC:感谢430陪伴我们的DOTA2国际邀请赛岁月
2016/06/29 DOTA
Python使用matplotlib的pie函数绘制饼状图功能示例
2018/01/08 Python
python如何重载模块实例解析
2018/01/25 Python
python和shell监控linux服务器的详细代码
2018/06/22 Python
Python 读取某个目录下所有的文件实例
2018/06/23 Python
基于python的itchat库实现微信聊天机器人(推荐)
2019/10/29 Python
python实现将列表中各个值快速赋值给多个变量
2020/04/02 Python
python中使用input()函数获取用户输入值方式
2020/05/03 Python
CSS3中Animation动画属性用法详解
2016/07/04 HTML / CSS
荷兰网上药店:Drogisterij.net
2019/09/03 全球购物
JSP&Servlet技术面试题
2015/05/21 面试题
求职信内容考虑哪几点
2013/10/05 职场文书
2014两会学习心得:榜样精神伴我行
2014/03/17 职场文书
2014年专项整治工作总结
2014/11/17 职场文书
PyTorch中permute的使用方法
2022/04/26 Python