【Django-功能优化】存储、循环、操作选择对代码性能的影响

news2024/11/15 5:56:11

功能开发背景

港口货轮需要进行集装箱的装卸任务:

image-20230625174847439

船上的每一个集装箱,可以用三个维度的坐标来唯一定位:(bay, column, layer),这三个维度结合其他一些固有信息,构成了一个箱子的字段属性,存储在箱子数据表中。

image-20230625201800934

现在需要以bay为单位,对bay内所有column、layer下的箱子,按照特有作业优先级进行作业顺序的编号(优先级从高到低:40尺-单钩箱子>20尺-双钩箱子>20尺-单钩箱子)。

即某个bay下,所有column最上层的箱子,统计他们的优先级,取其优先级最高的特定优先级进行作业,等到所有column最高层的箱子没有该优先级的箱子,按照低一级的优先级进行作业。如此循环往复三个优先级,直到所有的箱子都被编上作业顺序。

实现思路

大意如此,细节上的约束限制条件,不展开描述

  1. 获取船舶所有的bay信息
  2. 针对每一个bay信息,通过Django ORM查询数据库并返回满足条件的箱子集合
  3. 获取这些箱子集合包含的column、layer,并存储在列表中
  4. 两层循环遍历每一个箱子(按照层数和列数:从上到下(层),从左到右(列)遍历):

不用双层遍历的算法难度太大,构思不出来

for lay in layers:
    for col in columns:
        pass
  1. 在 优先级i 遍历的过程中,如果某列的箱子优先级不是i,则标记该列,在i优先级的后续遍历过程中不再考虑该列的箱子。

代码实现细节带来的速度差异

箱子数量计数

# 老版
for lay in layers:
    for col in lay_columns[lay]:
        boxes_selected = temp_queryset.filter(box_column=col, box_layer=lay)
        # ========================================
        len_boxes_selected = boxes_selected.count()
		# ========================================
        
        if len_boxes_selected == 2:
            if boxes_selected[0].is_work_together == 1:
                self.boxes_number_1(boxes_selected)
            else:
                self.boxes_number_2(boxes_selected)

        elif len_boxes_selected == 1:
            self.boxes_number_1(boxes_selected)

        else:
            pass

# 新版
for lay in layers:
    for col in lay_columns[lay]:
        boxes_selected = temp_queryset.filter(box_column=col, box_layer=lay)
        # ========================================
        len_boxes_selected = len(boxes_selected)
		# ========================================
        
        if len_boxes_selected == 2:
            if boxes_selected[0].is_work_together == 1:
                self.boxes_number_1(boxes_selected)
            else:
                self.boxes_number_2(boxes_selected)

        elif len_boxes_selected == 1:
            self.boxes_number_1(boxes_selected)

        else:
            pass

对计数后的查询集进行修改操作,用len()函数要比count()函数,效率高一点

参考文章:https://blog.csdn.net/qq_39187019/article/details/108170726

箱子列和层数的获取方式

# 老版
layer = [86, 84, 82, 80, 78, 76]
column = [16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15]


# 新版
layer = [86, 84, 82, 80, 78, 76]
column = {
    86:[16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15],
    84:[14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11],
    82:[16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15],
    80:[10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15],
    78:[16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15],
    76:[16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7]
}

老版:获取这个bay下所有箱子里面,涉及到的列和层

  1. 该方法十分方便的获取列和层
  2. 但是存在冗余,特定列,特定层下是没有箱子的,比如:(84, 16)

新版:获取这个bay下所有箱子里面,涉及到的层,再获取特定层下面涉及到的列信息

  1. 该方法相较于老版,在获取列信息上会更加耗时
  2. 但是不存在冗余,只要是遍历到的层、列,就一定能保证有箱子

整体计算下来,新版更加节省时间

结果存储方式的不同

# 老版本
self.numbered_boxes |= changed_queryset

# 新版本
for box in changed_queryset:
	self.numbered_boxes.append(box)

老版:对已经编号的箱子集合进行并集操作

  1. 最终的存储结果:<class ‘django.db.models.query.QuerySet’>

新版:在对箱子编号的时候,对箱子进行append操作

  1. 最终的存储结果:[<class ‘icwp_basic_data.models.Ship_Box_Data’>, <class ‘icwp_basic_data.models.Ship_Box_Data’>, …]

运算结果对比

上述改动,都是逐一改变的,每次改变都会有时间上的节省。

下边仅展示最终结果

数据量:10307条数据

image-20230625195855614

运算时间

版本运算时长(s)
老版316
新版143

老版

image-20230625200430898

新版

image-20230625200939949

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684316.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

百度的人脸识别的技术

百度的人脸识别的技术 1.基本概念 分组&#xff1a;分组ID&#xff08;group_id&#xff09;&#xff1a;分组ID用于对一组相关的人脸进行分组和管理。你可以根据自己的需求&#xff0c;将不同的人脸数据分配到不同的分组中。例如&#xff0c; 你可以根据人员的职位、部门或其…

Nginx优化安全防盗链

1.Nginx的页面优化 1.1 Nginx的网页压缩 在Nginx的ngx_http_gzip_module压缩模块提供对文件内容压缩的功能。进行相关的配置修改&#xff0c;就能实现Nginx页面的压缩&#xff0c;达到节约带宽&#xff0c;提升用户访问速度 1.2 配置Nginx的图片缓存 当Nginx将网页数据返回给…

阿里云企业邮箱免费版、标准版、集团版和尊享版区别

阿里云企业邮箱版本分为免费版、标准版、集团版和尊享版&#xff0c;除了价格区别&#xff0c;功能方面有什么差异&#xff1f;如何选择企业邮箱版本&#xff1f;免费版0元适合初创型企业&#xff0c;标准版适合大、中、小型企业使用&#xff0c;涉及子公司之间邮箱通讯可以选择…

jQuery学习

原生实现计数器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wi…

getopt_long 函数的使用

getopt_long 函数的使用网上已经有很多了&#xff0c;这里只是记录一下方便自己后续查找。首先函数原型声明&#xff1a; #include <getopt.h>int getopt_long(int argc, char *argv[],const char *optstring,const struct option *longopts, int *longindex); 函数是用…

Navicat使用导入向导批量插入数据到数据库

Mybatis,"可持久层数据库框架" Html,"超文本标记语言" Css,"网页外设计语言" JavaScript,"用户行为交互" Jquery,"提升网页开发效率的一种框架" Vue,"前端开发框架" Vant,"前开发预装组件库" git,"…

SM2算法对比RSA算法,有哪些优势?

SM2算法和RSA算法都是公钥密码算法&#xff0c;SM2算法是一种更先进安全的算法&#xff0c;在安全性能、速度性能等方面都优于RSA算法&#xff0c;在我国商用密码体系中被用来替换RSA算法。国家密码管理局于2010年12月17日发布了SM2算法&#xff0c;并要求现有的基于RSA算法的电…

《面试1v1》Redis基础

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Golang/Python 调用 openAI 的API 详解

学习目标&#xff1a; OpenAI API介绍 学习如何通过 Golang 使用 OpenAI 的 API OpenAI 的常用的参数及其说明 了解OpenAI API 中令牌&#xff08;tokens) OpenAI API 提供了几个不同的终端点&#xff08;endpoints&#xff09;和模式&#xff08;modes&#xff09; 复杂和…

【已解决】Java 中导入excel时使用 trim() 无法去除空格的解决方法

使用trim无法去除空格的解决方法 一、问题描述二、原因分析三、解决方案方案一&#xff1a;使用正则表达式方案二&#xff1a;使用String.strip()方案三&#xff1a;使用 hutool的 StrUtil.trim()方法 四、总结 一、问题描述 在excel导入操作时&#xff0c;读取cell中的字符串…

自学Python 69 Selenium八大元素定位方法(新版BY方法)

Python Selenium八大元素定位方法(新版BY方法) 文章目录 Python Selenium八大元素定位方法(新版BY方法)前言一、常用的八种定位方法&#xff08;新旧对比&#xff09;二、查看网页元素三、八大元素定位示例1、id定位2、name定位3、class定位4、tag定位5、link定位6、partial_li…

MySQL - 第9节 - MySQL内外连接

目录 1.内连接 2.外连接 2.1.左外连接 2.2.右外连接 3.简单案例 1.内连接 • 表的连接分为内连接和外连接。 • 内连接实际上就是利用where 子句对两种表形成的笛卡儿积进行筛选&#xff0c;我们前面学习的查询都是内连接&#xff0c;也是在开发过程中使用的最多的连接查…

【C++】模板初级内容(函数模板,类模板)

文章目录 前言一、函数模板1.1 函数模板概念1.2函数模板格式1.3模板的原理&#xff1a;1.4函数模板的实例化 二、类模板2.1 类模板的定义格式2.2定义与声明分离要注意的点 前言 告诉编译器一个模子&#xff0c;让编译器根据不同的类型利用该模子来生成代码 模板分为函数模板与类…

MES系统常用的数据采集网关

随着制造业的数字化转型&#xff0c;MES&#xff08;制造执行系统&#xff09;在生产过程中的重要性日益凸显。MES系统作为连接企业资源和生产现场的桥梁&#xff0c;需要实时、准确地采集和整合工业设备的数据&#xff0c;以支持生产调度、质量管理、库存控制等关键业务。为了…

探索Gradio Audio模块的change、clear和play方法

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

C#常见技能_封装

大家好&#xff0c;我是华山自控编程朱老师 前几天一个学员在学习C#与封装交互时,也不知道封装可以用来做什么 。下面我们就详细讲讲C# 和封装交互的相关知识。 C#是一种面向对象的编程语言&#xff0c;封装是面向对象编程中的一个重要概念&#xff0c;通过封装可以将数据和操…

CAN(1)-GD32

CAN-GD32 电路 CAN 是 Controller Area Network 的缩写,是 ISO 国际标准化的串行通信协议。 CAN总线的很多优点,使得它得到了广泛的应用,如传输速度最高到1Mbps, 通信距离最远到10km,无损位仲裁机制,多主结构。 CAN总线的标准 CAN总线标准之规定了物理层和数据链路层…

并发和并行的区别

目录 背景过程例子&#xff1a;定义&#xff1a;并发解决办法&#xff08;Redisson&#xff09;&#xff1a;解决并发步骤&#xff08;Redisson&#xff09;&#xff1a; 总结 背景 在设计Arpro第三版的时候马总提出了一个问题&#xff0c;我们认为人家表达是并发问题&#xf…

吉他如何实现内录or通过转接头和简易声卡连接电脑没有声音怎么办

目录 效果器or智能音箱 电吉他和效果器的连接 效果器和耳机or音箱连接 内录方法 为什么用6.5mm&#xff08;入&#xff09;转3.5mm&#xff08;出&#xff09;转接头内录无声音 整体连接图示 这篇文章我会以通俗的语言为初学者描述如何让电吉他“燃起来”&#xff0c;效果…

【每日算法 数据结构(C++)】—— 03 | 合并两个有序数组(解题思路、流程图、代码片段)

文章目录 01 | &#x1f451; 题目描述02 | &#x1f50b; 解题思路03 | &#x1f9e2; 代码片段 An inch of time is an inch of gold, but you can’t buy that inch of time with an inch of gold. An inch of time is an inch of gold, but you cant buy that inch of time…