Python3如何使用多线程升程序运行速度

作者:天外归云 时间:2023-02-06 05:11:42 

优化前后新老代码如下:


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倍

来源:https://www.cnblogs.com/LanTianYou/p/11498525.html

标签:Python,多线程,运行,速度
0
投稿

猜你喜欢

  • 浅析CMS生成静态页面的两种方案

    2008-03-17 12:51:00
  • 利用Anaconda完美解决Python 2与python 3的共存问题

    2022-05-16 17:51:43
  • 巧妙的Sql函数日期处理方法

    2009-05-25 17:59:00
  • python中对数据进行各种排序的方法

    2022-05-31 15:26:55
  • Java中@Pattern注解常用的校验正则表达式学习笔记

    2022-08-07 11:12:10
  • 数据库复制性能测试 推送模式性能测试

    2012-07-11 16:13:52
  • 利用Python编写个有趣的记仇本

    2022-08-25 19:20:20
  • 深入浅析pycharm中 Make available to all projects的含义

    2023-08-26 00:59:06
  • javascript制作loading动画效果 loading效果

    2024-02-26 18:50:24
  • MySQL8.0.20单机多实例部署步骤

    2024-01-13 13:46:37
  • python安装scipy的方法步骤

    2022-02-27 21:10:45
  • OpenCV图像修复cv2.inpaint()的使用

    2022-07-03 05:47:57
  • 如何使用python3获取当前路径及os.path.dirname的使用

    2023-07-22 06:29:37
  • Python实现快速傅里叶变换的方法(FFT)

    2022-09-18 07:21:47
  • 详解python编译器和解释器的区别

    2023-06-26 03:53:09
  • Django单元测试工具test client使用详解

    2021-04-11 22:25:58
  • MySQL连接查询实例详解

    2024-01-28 11:39:13
  • Python实现在Excel文件中写入图表

    2023-11-20 17:13:03
  • 解读MySQL的InnoDB引擎日志工作原理

    2011-01-04 19:59:00
  • ASP.NET Core中的Options选项模式

    2024-05-13 09:16:59
  • asp之家 网络编程 m.aspxhome.com