如何提高python 中for循环的效率


Posted in Python onApril 15, 2020

对于某个城市的出租车数据,一天就有33210000条记录,如何将每辆车的数据单独拎出来放到一个专属的文件中呢?

思路很简单:

就是循环33210000条记录,将每辆车的数据搬运到它该去的文件中。

但是对于3000多万条数据,一个一个循环太消耗时间,我花了2个小时才搬运了60万数据,算算3000万我需要花费100个小时,也就需要4-5天。并且还需要保证这五天全天开机,不能出现卡机的事故。

因此,需要使用并行进行for循环的技巧:

由于3000万数据放到csv中导致csv打不开,因此我就把一个csv通过split软件将其切分成每份60万,共53个csv。

我原来的思路是读取文件夹,获取由每一个60万的csv文件组成的列表,再分别对每一个60万的csv进行处理。实质上还是循环33210000次,并行for循环就是同时处理几个60万的csv文件,就能成倍的减少时间消耗。

并行进行for循环是受下面的方法启发:

我之前的做法类似这样:

words = ['apple', 'bananan', 'cake', 'dumpling']
  for word in words:
    print word

并行for循环类似这样:

from multiprocessing.dummy import Pool as ThreadPool
items = list()
pool = ThreadPool()
pool.map(process, items)
pool.close()
pool.join()

其中,process是进行处理的函数

实例代码如下:

# -*- coding: utf-8 -*-
import time
from multiprocessing.dummy import Pool as ThreadPool
def process(item):
  print('正在并行for循环')
  print(item)
  time.sleep(5)
items = ['apple', 'bananan', 'cake', 'dumpling']
pool = ThreadPool()
pool.map(process, items)
pool.close()
pool.join()

补充知识:Python3用多线程替代for循环提升程序运行速度

优化前后新老代码如下:

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 中for循环的效率就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python开发的HTTP库requests详解
Aug 29 Python
python selenium自动上传有赞单号的操作方法
Jul 05 Python
python 使用sys.stdin和fileinput读入标准输入的方法
Oct 17 Python
Python简单获取二维数组行列数的方法示例
Dec 21 Python
在Python中,不用while和for循环遍历列表的实例
Feb 20 Python
Python拆分大型CSV文件代码实例
Oct 07 Python
Python Gluon参数和模块命名操作教程
Dec 18 Python
Pycharm 2020.1 版配置优化的详细教程
Aug 07 Python
python 实现一个图形界面的汇率计算器
Nov 09 Python
appium+python自动化配置(adk、jdk、node.js)
Nov 17 Python
python读取pdf格式文档的实现代码
Apr 01 Python
Python中tkinter的用户登录管理的实现
Apr 22 Python
ipython jupyter notebook中显示图像和数学公式实例
Apr 15 #Python
解决 jupyter notebook 回车换两行问题
Apr 15 #Python
Python使用monkey.patch_all()解决协程阻塞问题
Apr 15 #Python
使用python处理题库表格并转化为word形式的实现
Apr 14 #Python
浅谈Python中re.match()和re.search()的使用及区别
Apr 14 #Python
Jupyter加载文件的实现方法
Apr 14 #Python
利用jupyter网页版本进行python函数查询方式
Apr 14 #Python
You might like
php adodb操作mysql数据库
2009/03/19 PHP
PHP模板引擎Smarty内建函数section,sectionelse用法详解
2016/04/11 PHP
详解php协程知识点
2018/09/21 PHP
如何判断图片地址是否失效
2007/02/02 Javascript
二级域名或跨域共享Cookies的实现方法
2008/08/07 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
使用js声明数组,对象在jsp页面中(获得ajax得到json数据)
2013/11/05 Javascript
JavaScript数字和字符串转换示例
2014/03/26 Javascript
Javascript Object 对象学习笔记
2014/12/17 Javascript
JavaScript中原型和原型链详解
2015/02/11 Javascript
jQuery实现气球弹出框式的侧边导航菜单效果
2015/09/22 Javascript
JavaScript预解析及相关技巧分析
2016/04/21 Javascript
微信小程序 swiper组件详解及实例代码
2016/10/25 Javascript
nodejs个人博客开发第三步 载入页面
2017/04/12 NodeJs
详解Angular2中Input和Output用法及示例
2017/05/21 Javascript
AngularJS中controller控制器继承的使用方法
2017/11/03 Javascript
vue awesome swiper异步加载数据出现的bug问题
2018/07/03 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
javascript单张多张图无缝滚动实例代码
2020/05/10 Javascript
[02:08]2018年度CS GO枪械皮肤设计大赛优秀作者-完美盛典
2018/12/16 DOTA
[54:17]DOTA2-DPC中国联赛定级赛 RNG vs iG BO3第二场 1月10日
2021/03/11 DOTA
Python实现windows下模拟按键和鼠标点击的方法
2015/03/13 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
Python3 hashlib密码散列算法原理详解
2020/03/30 Python
css3实现小箭头各种图形效果
2020/07/08 HTML / CSS
将SVG图引入到HTML页面的实现
2019/09/20 HTML / CSS
澳大利亚办公室装修:JasonL Office Furniture
2019/06/25 全球购物
四群教育工作实施方案
2014/03/26 职场文书
领导干部个人对照检查材料(群众路线)
2014/09/26 职场文书
社区党支部承诺书
2015/04/29 职场文书
为自己工作观后感
2015/06/11 职场文书
百年校庆宣传标语口号
2015/12/26 职场文书
浅谈什么是SpringBoot异常处理自动配置的原理
2021/06/21 Java/Android
Kubernetes关键组件与结构组成介绍
2022/03/31 Servers
基于PyQt5制作一个群发邮件工具
2022/04/08 Python
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS