【随想】代码优化论

序言:时间是我们最宝贵的财富,珍惜手上的每个时分

         

目录

1.非必要,不修改、不优化

2.需修改、需优化、搞彻底


        随着工作年限的增长,接触到的二手代码也越来越多,无论是同事离职留下的垃圾代码,还是接手烂摊子项目代码,都绕不开这个主题:代码优化。

        当然并非所有的代码都需要去优化,毕竟在能用的情况下,优化代码带来的价值远可能低于付出的成本。

        我遵循的准则

        1)非必要,不修改、不优化。

        2)需修改、需优化、搞彻底。

        接手代码的第一步:结合项目整体需求,分析代码是否需要优化。

1.非必要,不修改、不优化

        

        例如:前阵子接手的报表功能模块主要功能代码如下,

    def compute_sale_cost(self, invoice_lines):sale_cost = 0for sale_cost_id in self.env.company.in_come_cost_report_config_id.sale_cost_ids:invoice_line_ids = invoice_lines.filtered(lambda x: x.account_id.id == sale_cost_id.account_id.id)# print('111111',invoice_lines)if sale_cost_id.type == 'debit':sale_cost += sum(invoice_line_ids.mapped('debit'))if sale_cost_id.type == 'credit':sale_cost += sum(invoice_line_ids.mapped('credit'))return sale_costdef compute_material_cost(self, invoice_lines):material_cost = 0for material_cost_id in self.env.company.in_come_cost_report_config_id.material_cost_ids:invoice_line_ids = invoice_lines.filtered(lambda x: x.account_id.id == material_cost_id.account_id.id)if material_cost_id.type == 'debit':material_cost += sum(invoice_line_ids.mapped('debit'))if material_cost_id.type == 'credit':material_cost += sum(invoice_line_ids.mapped('credit'))return material_costdef compute_labor_cost(self, invoice_lines):labor_cost = 0for labor_cost_id in self.env.company.in_come_cost_report_config_id.labor_cost_ids:invoice_line_ids = invoice_lines.filtered(lambda x: x.account_id.id == labor_cost_id.account_id.id)if labor_cost_id.type == 'debit':labor_cost += sum(invoice_line_ids.mapped('debit'))if labor_cost_id.type == 'credit':labor_cost += sum(invoice_line_ids.mapped('credit'))return labor_costdef compute_mrp_cost(self, invoice_lines):mrp_cost = 0for mrp_cost_id in self.env.company.in_come_cost_report_config_id.mrp_cost_ids:invoice_line_ids = invoice_lines.filtered(lambda x: x.account_id.id == mrp_cost_id.account_id.id)if mrp_cost_id.type == 'debit':mrp_cost += sum(invoice_line_ids.mapped('debit'))if mrp_cost_id.type == 'credit':mrp_cost += sum(invoice_line_ids.mapped('credit'))return mrp_cost@api.modeldef get_now_data(self, *kw):try:wizard_id = kw[0]['report_id']allowed_company_ids = kw[0]['allowed_company_ids']wizard_id = self.env['ro.income.cost.report.wizard'].sudo().search([('id', '=', wizard_id)])period_ids = wizard_id.period_ids# 会计日期数据存放列表period_data = []# 清洗会计日期数据for period_id in period_ids:period_dict = {'period_id': period_id,'date_start': period_id.date_start,'date_end': period_id.date_end}period_data.append(period_dict)partner_ids = wizard_id.partner_ids# 客户数据存放列表partner_data = []if not partner_ids:partner_ids = self.env['res.partner'].sudo().search([])# 清洗客户数据for partner_id in partner_ids:partner_dict = {'partner_id': partner_id,'id': partner_id.id}partner_data.append(partner_dict)# 所有客户的订单明细行sale_order_line_ids = self.env['sale.order.line'].sudo().search([('order_partner_id', 'in', partner_ids.ids), ('company_id', 'in', allowed_company_ids)])# 销售订单明细行存放列表sale_order_line_data = []for sale_order_line_id in sale_order_line_ids:out_going_number = sale_order_line_id.order_id.picking_ids.mapped('name')out_going_number = ','.join(out_going_number)# print(sale_order_line_id.invoice_lines)if wizard_id.invoice_range:invoice_lines = sale_order_line_id.invoice_lines.filtered(lambda x: x.move_id.state == 'posted' or x.move_id.state == 'draft' or x.move_id.state == 'approval' or x.move_id.state == 'approved')else:invoice_lines = sale_order_line_id.invoice_lines.filtered(lambda x:x.move_id.state == 'posted')sale_order_line_dict = {'sale_order_line_id': sale_order_line_id,'sale_order_name': sale_order_line_id.order_id.name,'out_going_number': out_going_number,'partner_name': sale_order_line_id.order_partner_id.name,'default_code': sale_order_line_id.product_id.default_code if sale_order_line_id.product_id.default_code else '/','product_name': sale_order_line_id.product_id.name,'product_uom_qty': sale_order_line_id.product_uom_qty,'amount': sale_order_line_id.price_subtotal,'amount_tax': sale_order_line_id.price_total,'date_order': sale_order_line_id.create_date,'invoice_lines': invoice_lines}sale_order_line_data.append(sale_order_line_dict)# 遍历期间data = []for period_id in period_data:# 拿到期间内的明细行sale_order_line_ids = [d for d in sale_order_line_data ifperiod_id['date_start'] < d['date_order'].date() < period_id['date_end']]for sale_order_line_id in sale_order_line_ids:sale_cost = wizard_id.compute_sale_cost(sale_order_line_id['invoice_lines'])material_cost = wizard_id.compute_material_cost(sale_order_line_id['invoice_lines'])labor_cost = wizard_id.compute_labor_cost(sale_order_line_id['invoice_lines'])mrp_cost = wizard_id.compute_mrp_cost(sale_order_line_id['invoice_lines'])row = [sale_order_line_id['sale_order_name'], sale_order_line_id['out_going_number'],sale_order_line_id['partner_name'], sale_order_line_id['default_code'],sale_order_line_id['product_name'], sale_order_line_id['product_uom_qty'],sale_order_line_id['amount'], sale_order_line_id['amount_tax'],sale_cost, material_cost, labor_cost, mrp_cost]if wizard_id.filter_zero:result = all(x == 0 for x in row[5:]) or all(x == '/' for x in row[5:])if result is True:continuedata.append(row)period_name = ','.join(period_ids.mapped('name'))except Exception as e:print(e)data = []period_name = ''# print(period_name)result = {# 'header': headers,'body': data,'period_name': period_name,'company_name': self.env.company.name}return result

        细细品味(劝你别品)如上代码,并依据需求测试,可以分析得到:

                1、功能可用,主逻辑清晰

                2、核心函数get_now_data代码冗余(构造多个无用数组)

                3、计算方法compute_xx_cost 方法冗余(实际为同一个计算方法,不同参数)

        可优化的点

                1、合并优化 compute_xx_cost 方法为一个方法

                2、优化冗余构造数组

        综上分析, 虽然代码冗余,但是功能完整且基本不影响用户操作,且后续不需要更新升级。即:非必要。

        那么我会会遵循 1)非必要,不修改、不优化的规则,

2.需修改、需优化、搞彻底。

        例如:还是前阵子接手的另一个报表功能模块,主要功能代码如下        

        200多行实在展开困难,我节选给各位感受感受:

        其一

            # 处理日期for period_id in wizard_id.fiscalyear_id.period_ids:if period_id.date_start.month == 1:fiscalyear_data['one_date_start'] = period_id.date_startfiscalyear_data['one_date_end'] = period_id.date_endelif period_id.date_start.month == 2:fiscalyear_data['two_date_start'] = period_id.date_startfiscalyear_data['two_date_end'] = period_id.date_endelif period_id.date_start.month == 3:fiscalyear_data['three_date_start'] = period_id.date_startfiscalyear_data['three_date_end'] = period_id.date_endelif period_id.date_start.month == 4:fiscalyear_data['four_date_start'] = period_id.date_startfiscalyear_data['four_date_end'] = period_id.date_endelif period_id.date_start.month == 5:fiscalyear_data['five_date_start'] = period_id.date_startfiscalyear_data['five_date_end'] = period_id.date_endelif period_id.date_start.month == 6:fiscalyear_data['six_date_start'] = period_id.date_startfiscalyear_data['six_date_end'] = period_id.date_endelif period_id.date_start.month == 7:fiscalyear_data['seven_date_start'] = period_id.date_startfiscalyear_data['seven_date_end'] = period_id.date_endelif period_id.date_start.month == 8:fiscalyear_data['eight_date_start'] = period_id.date_startfiscalyear_data['eight_date_end'] = period_id.date_endelif period_id.date_start.month == 9:fiscalyear_data['nine_date_start'] = period_id.date_startfiscalyear_data['nine_date_end'] = period_id.date_endelif period_id.date_start.month == 10:fiscalyear_data['ten_date_start'] = period_id.date_startfiscalyear_data['ten_date_end'] = period_id.date_endelif period_id.date_start.month == 11:fiscalyear_data['eleven_date_start'] = period_id.date_startfiscalyear_data['eleven_date_end'] = period_id.date_endelif period_id.date_start.month == 12:fiscalyear_data['twelve_date_start'] = period_id.date_startfiscalyear_data['twelve_date_end'] = period_id.date_end

其二:

            all_year_amount = 0later_year_amount = 0one_all = 0two_all = 0three_all = 0four_all = 0five_all = 0six_all = 0seven_all = 0eight_all = 0nine_all = 0ten_all = 0eleven_all = 0twelve_all = 0for child in data:if child[0] == '合计':breakone_all += child[2]two_all += child[3]three_all += child[4]four_all += child[5]five_all += child[6]six_all += child[7]seven_all += child[8]eight_all += child[9]nine_all += child[10]ten_all += child[11]eleven_all += child[12]twelve_all += child[13]all_year_amount += child[14]later_year_amount += child[16]print(all_year_amount)if all_year_amount != 0:one_rate = one_all / all_year_amount * 100two_rate = two_all / all_year_amount * 100three_rate = three_all / all_year_amount * 100four_rate = four_all / all_year_amount * 100five_rate = five_all / all_year_amount * 100six_rate = six_all / all_year_amount * 100seven_rate = seven_all / all_year_amount * 100eight_rate = eight_all / all_year_amount * 100nine_rate = nine_all / all_year_amount * 100ten_rate = ten_all / all_year_amount * 100eleven_rate = eleven_all / all_year_amount * 100twelve_rate = twelve_all / all_year_amount * 100else:one_rate = 0two_rate = 0three_rate = 0four_rate = 0five_rate = 0six_rate = 0seven_rate = 0eight_rate = 0nine_rate = 0ten_rate = 0eleven_rate = 0twelve_rate = 0

其三:

        print(cost_id)# 筛选一月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['one_date_start'], fiscalyear_data['one_date_end'])# 一月份该科目销售费用one_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选二月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['two_date_start'], fiscalyear_data['two_date_end'])# 二月份该科目销售费用two_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选三月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['three_date_start'], fiscalyear_data['three_date_end'])# 三月份该科目销售费用three_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选四月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['four_date_start'], fiscalyear_data['four_date_end'])# 四月份该科目销售费用four_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选五月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['five_date_start'], fiscalyear_data['five_date_end'])# 五月份该科目销售费用five_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选六月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['six_date_start'], fiscalyear_data['six_date_end'])# 六月份该科目销售费用six_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选七月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['seven_date_start'], fiscalyear_data['seven_date_end'])# 七月份该科目销售费用seven_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选八月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['eight_date_start'], fiscalyear_data['eight_date_end'])# 八月份该科目销售费用eight_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选九月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['nine_date_start'], fiscalyear_data['nine_date_end'])# 九月份该科目销售费用nine_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选十月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['ten_date_start'], fiscalyear_data['ten_date_end'])# 十月份该科目销售费用ten_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选十一月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['eleven_date_start'], fiscalyear_data['eleven_date_end'])# 十一月份该科目销售费用eleven_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)# 筛选十二月内该科目的凭证account_move_line_filtered_ids = self.compute_line_ids(cost_id, account_move_line_ids, fiscalyear_data['twelve_date_start'], fiscalyear_data['twelve_date_end'])# 十二月份该科目销售费用twelve_cost_amount = self.compute_amount(cost_type, account_move_line_filtered_ids)return one_cost_amount, two_cost_amount, three_cost_amount, four_cost_amount, five_cost_amount, six_cost_amount, seven_cost_amount, eight_cost_amount, nine_cost_amount, ten_cost_amount, eleven_cost_amount, twelve_cost_amount

        OKOK,难以想象,这里总共300多行代码,是以什么样的毅力写下来的?脑子里蹦出的是拉三(拉赫玛尼诺夫第三钢琴协奏曲)的旋律,以及拉三的趣闻。

        好笑归好笑,但是这代码是有问题的,测时候发现数据不对,我们进一步分析:

                1、功能不可用,主逻辑不清晰

                2、核心函数get_now_data代码冗余 

                        1)冗余循环

                        2)冗余数组构造

                        3)冗余变量设置

       当我们看到 功能不可用,且主逻辑不清晰的代码时,请一定放弃抵抗不要在原功能上修改,请直接重新捋逻辑,彻底重构,否则你将陷入 前人留给你的逻辑漩涡中无法自拔!

        这是血泪的教训,你觉得似乎只是一个小问题,但是永远改不好!

        最后我遵循   2)需修改、需优化、搞彻底的规则,将其完全重构:既减少了重新阅读代码,debugger的时间,也增加了代码的可读性,为后续更新升级提供良好基础,降低屎山代码形成的可能性。

        完全重构后的代码:

        其一、二、三的功能重构

        for account_id in account_ids:amount = 0val = ['[%s]%s' % (account_id.code, account_id.name)]for period_id in wizard_id.fiscalyear_id.period_ids:date_start = period_id.date_startdate_end = period_id.date_endaccount_move_ids = account_move_line_ids.filtered(lambda x: x.account_id == account_id and x.date >= date_start and x.date <= date_end)account_amount = sum(account_move_ids.mapped('credit'))val.append(account_amount)amount += account_amountval.append(amount)if all_amount != 0:percent = amount / all_amountelse:percent = 0val.append(percent * 100)last_amount = sum(last_year_account_move_line_ids.filtered(lambda x: x.account_id == account_id).mapped('credit'))val.append(last_amount)data.append(val)

        

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

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

相关文章

Java并发04之线程同步机制

文章目录 1 线程安全1.1 线程安全的变量1.2 Spring Bean1.3 如果保证线程安全 2 synchronized关键字2.1 Java对象头2.1.1 对象组成部分2.1.2 锁类型2.1.3 锁对象 2.2 synchronized底层实现2.2.1 无锁状态2.2.2 偏向锁状态2.2.3 轻量级锁状态2.2.4 重量级锁2.2.5 锁类型总结2.2.…

云手机结合自主ADB命令接口 提升海外营销效率

现在&#xff0c;跨境电商直播已经成为在线零售的重要渠道&#xff0c;在大环境下&#xff0c;确保直播应用的稳定性和用户体验至关重要。 云手机支持自主ADB命令接口&#xff0c;为电商直播营销提供了技术支持&#xff0c;使得应用开发、测试、优化和运维更加高效。 什么是A…

postman双击打不开的解决方案

postman双击打不开的解决方案 深入再深入 于 2022-05-09 15:45:56 发布 阅读量3.1k 收藏 2 点赞数 4 文章标签&#xff1a; postman 版权 右键属性 安装路径 更新版本 回滚 问题排查 关键词由CSDN通过智能技术生成 解决方案&#xff1a; 右键-属性&#xff0c;复制安装路…

puzzle(0611)《组合+图论》追捕问题

目录 一&#xff0c;追及问题 1&#xff0c;警察和小偷 2&#xff0c;旋转的4个硬币 3&#xff0c;抓狐狸 二&#xff0c;围堵问题 三&#xff0c;追及围堵 一&#xff0c;追及问题 1&#xff0c;警察和小偷 如下图&#xff0c;警察先走&#xff0c;警察和小偷轮流一人…

开源模型应用落地-FastAPI-助力模型交互-进阶篇(三)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…

【Git远程操作】理解分布式管理 | 创建远程仓库

目录 1.理解分布式管理 多人协作开发 2.创建远程仓库 2.1仓库名&路径 2.2初始化仓库&设置模板 1.理解分布式管理 目前我们学习的所有内容都是在本地来完成的。&#xff08;add /commit /版本撤销回退/分支管理&#xff09; Git是一个分布式 的版本控制系统。 分支…

c# listview控件调整标题显示顺序

右键点击listview,选择编辑列 修改DisplayIndex listview在成员位置点击上下箭头移动后&#xff0c;实际显示不会改变&#xff0c;因为DisplayIndex没有改变

IDEA的断点调试(Debug)

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试&#xff08;Debug&#xff09; 第七章 …

go-zero框架入门

go-zero框架环境的安装 goctl 若想用go-zero框架&#xff0c;还需要一些前置条件&#xff1a; 安装goctl go install github.com/zeromicro/go-zero/tools/goctllatest可以使用 goctl 命令查看是否安装成功 成功后安装protoc goctl env check --install --verbose --force…

云监控(华为) | 实训学习day2(10)

spring boot基于框架的实现 简单应用 - 用户数据显示 开发步骤 第一步&#xff1a;文件-----》新建---项目 第二步:弹出的对话框中,左侧选择maven,右侧不选任何内容. 第三步&#xff0c;选择maven后&#xff0c;下一步 第4步 &#xff1a;出现对话框中填写项目名称 第5步&…

【学术会议征稿】第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)

第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024) 2024 6th International Conference on Frontier Technologies of Information and Computer 第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)将在中国青岛举行&#xff0c;会期是2024年11月8-10日&#xff0c;为…

FOG Project 文件名命令注入漏洞复现(CVE-2024-39914)

0x01 产品简介 FOG是一个开源的计算机镜像解决方案,旨在帮助管理员轻松地部署、维护和克隆大量计算机。FOG Project 提供了一套功能强大的工具,使用户能够快速部署操作系统、软件和配置设置到多台计算机上,从而节省时间和精力。该项目支持基于网络的 PXE 启动、镜像创建和还…

Python:拆包

拆包 适用于元组和列表 coordinates (1, 2, 3) 如果想要获取这三个值 本来应该这样做 xcoordinates[0] ycoordinates[1] zcoordinates[2] python 特性&#xff1a;简化获取步骤 x, y, z coordinates 输出中全是变量名&#xff0c;可以直接用 , 连接 print(x, y, z)

Python | Leetcode Python题解之第257题二叉树的所有路径

题目&#xff1a; 题解&#xff1a; class Solution:def binaryTreePaths(self, root: TreeNode) -> List[str]:paths list()if not root:return pathsnode_queue collections.deque([root])path_queue collections.deque([str(root.val)])while node_queue:node node_…

鸿蒙语言基础类库:【@system.request (上传下载)】

上传下载 说明&#xff1a; 从API Version 6开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.request]。本模块首批接口从API version 4开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import request from system.re…

HarmonyOS ArkUi @CustomDialog 和promptAction.openCustomDialog踩坑以及如何选择

CustomDialog 内使用Link&#xff0c;如何正常使用 错误使用方式&#xff1a; 定义一个函数&#xff0c;在函数内使用弹窗&#xff0c;如下面代码showDialog&#xff1a; 这种使用方式&#xff0c;无法在自定义的CustomDialog内使用 Link&#xff0c;进行父子双向绑定&#x…

3、宠物商店智能合约实战(truffle智能合约项目实战)

3、宠物商店智能合约实战&#xff08;truffle智能合约项目实战&#xff09; 1-宠物商店环境搭建、运行2-webjs与宠物逻辑实现3-领养智能合约初始化4-宠物领养实现5-更新宠物领养状态 1-宠物商店环境搭建、运行 https://www.trufflesuite.com/boxes/pet-shop 这个还是不行 或者…

vue3前端开发-小兔鲜项目-图片懒加载的自定义标签

vue3前端开发-小兔鲜项目-图片懒加载的自定义标签&#xff01;很多大型网站&#xff0c;因为首页面渲染的内容太多了&#xff0c;然而有些用户&#xff0c;可能在顶部就发现了自己感兴趣的内容&#xff0c;直接就点击跳转去了其他页面&#xff0c;因此&#xff0c;完全没有必要…

插画感言:成都亚恒丰创教育科技有限公司

插画感言&#xff1a;笔触间的灵魂对话 在这个快节奏、高压力的时代&#xff0c;我们时常在寻找那些能够触动心灵、让灵魂得以片刻栖息的角落。而插画&#xff0c;这一融合了艺术与情感的独特形式&#xff0c;便如同一股清泉&#xff0c;缓缓流淌进每个人的心田&#xff0c;以…

visual studio配置xlnt

xlnt下载&#xff1a;github下载地址 下载后&#xff0c;打开cmake&#xff0c;设置源和目标 选择对应的VS版本和平台 生成之后&#xff0c;在xlnt文件夹中右键运行VS 打开之后如果没有发生报错&#xff0c;则生成->安装 &#xff08;如果此处发生报错&#xff0c;提示…