[本文出自天外归云的博客园]

优化前后新老代码如下:

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倍

Python3用多线程替代for循环提升程序运行速度的更多相关文章

  1. 【C# 线程】编译器代码优化技术 循环提升:Loop Hoisting

    转载自:https://gandalfliang.github.io/2019/01/15/loop-hoisting/ Loop Hoisting 在上篇文章中,提到 Loop Hoisting , ...

  2. [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

    [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...

  3. 巧用array_map()和array_reduce()替代foreach循环

    1.array_reduce( $arr , callable $callback ) 使用回调函数迭代地将数组简化为单一的值. 其中$arr 为输入数组,$callback($result , $v ...

  4. java多线程实现卖票小程序

    package shb.java.demo; /** * 多线程测试卖票小程序. * @Package:shb.java.demo * @Description: * @author shaobn * ...

  5. 在python3.6环境下使用cxfreeze打包程序

    在python3.6环境下使用cxfreeze打包程序 环境:python3.6 打包程序:aliens_invasion 原本想使用pyintaller 进行打包,使用pip的安装过程也没有问题,打 ...

  6. 加法运算替代 牛客网 程序员面试金典 C++ Python

    加法运算替代 牛客网 程序员面试金典 题目描述 请编写一个方法,实现整数的乘法.减法和除法运算(这里的除指整除).只允许使用加号. 给定两个正整数int a,int b,同时给定一个int type代 ...

  7. Java练习小题_猴子吃桃问题分别用for循环和while循环实现程序。

    要求说明: 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上想再吃时, ...

  8. zw.delphi不同版本程序运行速度测试

    { zw.delphi不同版本程序运行速度测试 delphi无论是开发,编译,还是运行,速度方面向来不差,笔者很少进行这种微粒度的优化,调试. 最近,因为项目需要,发现:同一个函数模块,差不多同样的代 ...

  9. 【Python3之多线程】

    一.threading模块 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性. 1.开启线程的两种方式(同Process) 方法一 from thr ...

随机推荐

  1. 【Linux】在linux上java工具jps jstat jinfo等命令找不到怎么办

    一.yum安装方式 1)搜索openjdk-devel相关的安装包 yum search java|grep jdk 2)安装对应的版本 yum install -y java-1.8.0-openj ...

  2. 定时任务工具Linux crontab命令详解

    crontab:定时任务的守护进程,精确到分,设计秒的我们一般写脚本  -->相当于闹钟        日志文件:  ll /var/log/cron*        编辑文件: vim /et ...

  3. webpack4.0报WARNING in configuration警告

    在进行webpack打包工作时,先进行如下步骤 1). 安装webpack:推荐全局命令  cnpm install webpack -g 查看webpack版本 webpack -v 2) . 此时 ...

  4. mysql查看表的属性 mysql将查询结果给临时变量

    查看所有的表show table status ; 查看具体的某张表show table status from xxdb like 'tm_properties' ; 查看具体的字段的意思 sele ...

  5. 纯数据结构Java实现(8/11)(Trie)

    欢迎访问我的自建博客: CH-YK Blog.

  6. 微服务学习之路(三)——实现RPC远程服务调用

    RPC(Remote Producedure Call)调用原理:服务消费者称为客户端,服务提供者称为服务端,处于不同网络地址,需要建立网络连接.建立连接后,双方还必须按照某种约定的协议进行网络通讯— ...

  7. MapTask工作机制

    (1)Read阶段:MapTask通过用户编写的RecordReader,从输入InputSplit中解析出一个个key/value. (2)Map阶段:该节点主要是将解析出的key/value交给用 ...

  8. MIME Type介绍 Content-Type 各种定义

    多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符.二进制格式附件等多种格 ...

  9. hdu1010-Tempter of the Bone-(dfs+奇偶剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=1010 翻译:有只狗被困了,S是起点,D是门,W是墙不能走,‘ . ’是可以走的路,走一次就会在1秒内坍塌,也就是 ...

  10. Gym100676 H. Capital City

    感觉题目都已经快把正解给说出来了...strongly connected的两个点的消耗为0,其实就是同一个边双连通分量里面的点消耗为0.然后缩一下点,再树形DP一下就完了.第一次写边双,但感觉挺简单 ...