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操作MySQL的一些基本方法
Aug 16 Python
python xml解析实例详解
Nov 14 Python
python基础教程项目四之新闻聚合
Apr 02 Python
python如何爬取个性签名
Jun 19 Python
python批量下载网站马拉松照片的完整步骤
Dec 05 Python
浅谈Python批处理文件夹中的txt文件
Mar 11 Python
python selenium爬取斗鱼所有直播房间信息过程详解
Aug 09 Python
django echarts饼图数据动态加载的实例
Aug 12 Python
Python3.8对可迭代解包的改进及用法详解
Oct 15 Python
django admin 添加自定义链接方式
Mar 11 Python
什么是python的必选参数
Jun 21 Python
在Tensorflow中实现leakyRelu操作详解(高效)
Jun 30 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
discuz7 phpMysql操作类
2009/06/21 PHP
PHP实用函数分享之去除多余的0
2015/02/06 PHP
PHP微信开发之模板消息回复
2016/06/24 PHP
一些mootools的学习资源
2010/02/07 Javascript
JS过滤url参数特殊字符的实现方法
2013/12/24 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
jquery操作checkbox实现全选和取消全选
2014/05/02 Javascript
jQuery学习笔记之toArray()
2014/06/09 Javascript
浅谈jQuery中ajaxPrefilter的应用
2016/08/01 Javascript
关于js原型的面试题讲解
2016/09/25 Javascript
bootstrap fileinput 上传插件的基础使用
2017/02/17 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
2017/06/07 jQuery
详解多页应用 Webpack4 配置优化与踩坑记录
2018/10/16 Javascript
mpvue 页面预加载新增preLoad生命周期的两种方式
2019/10/17 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
2020/06/17 Javascript
vue 里面的 $forceUpdate() 强制实例重新渲染操作
2020/09/21 Javascript
探索node之事件循环的实现
2020/10/30 Javascript
用Javascript实现发送短信验证码间隔功能
2021/02/08 Javascript
[01:25:09]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第二场
2014/05/24 DOTA
python写的一个squid访问日志分析的小程序
2014/09/17 Python
Python常用模块介绍
2014/11/21 Python
python每隔N秒运行指定函数的方法
2015/03/16 Python
在Python的Django框架中编写错误提示页面
2015/07/22 Python
基于Python实现通过微信搜索功能查看谁把你删除了
2016/01/27 Python
解析Mac OS下部署Pyhton的Django框架项目的过程
2016/05/03 Python
简单介绍一下pyinstaller打包以及安全性的实现
2020/06/02 Python
美国在线自行车商店:Jenson USA
2018/05/22 全球购物
Dockers鞋官网:Dockers Shoes
2018/11/13 全球购物
英国最大的在线亚洲杂货店:Red Rickshaw
2020/03/22 全球购物
开工庆典邀请函范文
2014/01/16 职场文书
学生上课看漫画的检讨书
2014/09/26 职场文书
2015年幼儿园安全工作总结
2015/05/12 职场文书
四年级作文之植物
2019/09/20 职场文书
Python编程中Python与GIL互斥锁关系作用分析
2021/09/15 Python
python数字类型和占位符详情
2022/03/13 Python
关于EntityWrapper的in用法
2022/03/22 Java/Android