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 相关文章推荐
Win10下Python环境搭建与配置教程
Nov 18 Python
对python使用http、https代理的实例讲解
May 07 Python
python随机在一张图像上截取任意大小图片的方法
Jan 24 Python
解决django前后端分离csrf验证的问题
Feb 03 Python
详解Python odoo中嵌入html简单的分页功能
May 29 Python
Python实现搜索算法的实例代码
Jan 02 Python
python matplotlib imshow热图坐标替换/映射实例
Mar 14 Python
django ObjectDoesNotExist 和 DoesNotExist的用法
Jul 09 Python
python-图片流传输的思路及示例(url转换二维码)
Dec 21 Python
详解如何使用Pytest进行自动化测试
Jan 14 Python
关于探究python中sys.argv时遇到的问题详解
Feb 23 Python
利用Python+OpenCV三步去除水印
May 28 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实现MVC开发得最简单的方法――模型
2007/04/10 PHP
程序员编程十条戒律
2009/07/09 PHP
php面向对象全攻略 (八)重载新的方法
2009/09/30 PHP
PHP实现GIF图片验证码
2015/11/04 PHP
thinkPHP简单实现多个子查询语句的方法
2016/12/05 PHP
Apache+PHP+MySQL搭建PHP开发环境图文教程
2020/08/06 PHP
流量统计器如何鉴别C#:WebBrowser中伪造referer
2015/01/07 Javascript
JS网页在线获取鼠标坐标值的方法
2015/02/28 Javascript
jQuery实现可用于博客的动态滑动菜单
2015/03/09 Javascript
基于OL2实现百度地图ABCD marker的效果
2015/10/01 Javascript
jQuery中bind(),live(),delegate(),on()绑定事件方法实例详解
2016/01/19 Javascript
js两种拼接字符串的简单方法(必看)
2016/09/02 Javascript
浅谈jQuery添加的HTML,JS失效的问题
2016/10/05 Javascript
Echarts基本用法_动力节点Java学院整理
2017/08/11 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
关于vue编译版本引入的问题的解决
2018/09/17 Javascript
axios取消请求的实践记录分享
2018/09/26 Javascript
jQuery zTree插件使用简单教程
2019/08/16 jQuery
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
详解Python中contextlib上下文管理模块的用法
2016/06/28 Python
对Python 简单串口收发GUI界面的实例详解
2019/06/12 Python
Python计算机视觉里的IOU计算实例
2020/01/17 Python
python异步Web框架sanic的实现
2020/04/27 Python
Python pip安装模块提示错误解决方案
2020/05/22 Python
基于python和flask实现http接口过程解析
2020/06/15 Python
序列化Python对象的方法
2020/08/01 Python
使用tkinter实现三子棋游戏
2021/02/25 Python
Superdry极度乾燥官网:日本街头风格,纯英国制造品牌
2016/10/31 全球购物
拾金不昧的表扬信
2014/01/16 职场文书
团购业务员岗位职责
2014/03/15 职场文书
公关活动策划方案
2014/05/25 职场文书
帮一个朋友写的求职信
2014/08/09 职场文书
2014年度工作总结报告
2014/12/15 职场文书
财政局个人年终总结
2015/03/03 职场文书
小兵张嘎电影观后感
2015/06/03 职场文书
工作感言一句话
2015/08/01 职场文书