当前位置: 首页 > news >正文

关于gas费优化问题

关于gas费优化问题

首先我们先来看一下这段代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] memory nums) external{for(uint i = 0;i<nums.length;i+=1){bool isEven = nums[i] % 2 == 0;bool isLessThan99 = nums[i] < 99;if(isEven && isLessThan99){total += nums[i];}}}
}

在这段代码中定义了一个total的状态变量,并且将其传入数组的偶数以及小于99的数去进行累加。

当我们一开始运行sum方法的时候,我们可以看出第一次执行的gas费用为

28654

现在我们开始第一个优化:将memory改为calldata

contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] calldata nums) external{for(uint i = 0;i<nums.length;i+=1){bool isEven = nums[i] % 2 == 0;bool isLessThan99 = nums[i] < 99;if(isEven && isLessThan99){total += nums[i];}}}
}

此时我们再看看所需要用到的gas费用,此时少了2000左右

26909

为什么会这样呢?

我们对比一下calldata和memory的区别

在Solidity中,calldata是指函数调用参数的存储位置。而memory是在函数内部声明的临时变量的存储位置。

使用calldatamemory更能节省gas费用的原因是,calldata是只读的,在函数执行期间不能被修改。相反,memory中的数据可以在函数执行期间被修改,这意味着如果你使用memory存储大数据结构,每次修改都需要消耗更多的gas费用。

在这个场景中我们可以看到似乎nums作为一个入参似乎并不需要被改变,所以这里我们直接用calldata即可。

我们再来看看循环体内部

我们发现这里面的total这个状态变量,在每一次循环里面都会将total里面的重新赋值,这种在整体状态变量层面的操作实际上是非常浪费gas的。

我们不妨换一种思路,将total抽离到循环外,方法内单独设置一个变量去将total拷贝到内存中去,也就是我们每次累加的是内存中的一个变量,这样并不会写入状态变量。最后再循环结束后再一次性的将结果写入到状态变量中。

代码如下:

contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] calldata nums) external{uint _total = total;for(uint i = 0;i<nums.length;i+=1){bool isEven = nums[i] % 2 == 0;bool isLessThan99 = nums[i] < 99;if(isEven && isLessThan99){_total += nums[i];}}total = _total;}
}

此时我们可以执行看看gas费用的消耗,此时又节省了200左右

26698

我们再观察一下里面还有什么地方可以优化的

不难看出里面其实isEven和isLessThan99其实没必要单独给他每一次都赋值,我们直接给他合并到条件判断里面就好,合并后的效果如下:

contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] calldata nums) external{uint _total = total;for(uint i = 0;i<nums.length;i+=1){if(nums[i] % 2 == 0 && nums[i] < 99){_total += nums[i];}}total = _total;}
}

此时gas费用又节省了300左右

26380

我们再看看for(uint i = 0;i<nums.length;i+=1)这一段代码,i+=1实际上会将 i 的值复制到一个临时变量中,然后对 i 进行递增操作,最后再将临时变量的值返回给表达式。那有没有可以避免创建临时变量的方法呢?答案是有的:我们只需要改为++i即可

contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] calldata nums) external{uint _total = total;for(uint i = 0;i<nums.length;++i){if(nums[i] % 2 == 0 && nums[i] < 99){_total += nums[i];}}total = _total;}
}

此时的gas费用又节省了300多

26008

同样是刚才的循环,我们可以看出每一次循环中都要读取出数组的长度,这样每次循环都要执行这个方法,那么既然他的长度是不变的,我们不如直接给他存入缓存变量中。代码如下:

contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] calldata nums) external{uint _total = total;uint len = nums.length;for(uint i = 0;i<len;++i){if(nums[i] % 2 == 0 && nums[i] < 99){_total += nums[i];}}total = _total;}
}

此时gas费用又省了100多

25973

再看看循环内部的代码,我们针对循环体内数组的元素nums[i]其实可以提前复制到内存中,代码如下:

contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] calldata nums) external{uint _total = total;uint len = nums.length;for(uint i = 0;i<len;++i){uint num = nums[i];if(num % 2 == 0 && num < 99){_total += num;}}total = _total;}
}

此时gas费用又节省了200左右

25811

相关文章:

关于gas费优化问题

关于gas费优化问题 首先我们先来看一下这段代码 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract GasGolf{uint public total;//[1,2,3,4,5,100]function sum(uint[] memory nums) external{for(uint i 0;i<nums.length;i1){bool isEven nums[i] % 2…...

Linux——中断和时间管理(中)

目录 驱动中的中断处理 中断下半部 软中断 tasklet 工作队列 驱动中的中断处理 通过上一节的分析不难发现&#xff0c;要在驱动中支持中断&#xff0c;则需要构造一个 struct irqaction的结构对象&#xff0c;并根据IRQ 号加入到对应的链表中(因为 irq_des 已经在内核初始…...

嵌入式软件中常见的 8 种数据结构详解

目录 第一&#xff1a;数组 1、数组的应用 第二&#xff1a;链表 1、链表操作 2、链表的应用 第三&#xff1a;堆栈 1、堆栈操作 2、堆栈的应用 第四&#xff1a;队列 1、队列操作 2、队列的应用 第五&#xff1a;哈希表 1、哈希函数 2、哈希表的应用 第六&#…...

vue 修改当前路由参数并刷新界面

项目中经常用到的需求是在当前页面修改路由中的参数&#xff0c;并刷新页面。 我们只用this. r o u t e r . r e p l a c e 或者 t h i s . router.replace或者this. router.replace或者this.router.go是不行的&#xff0c;需配合下面的代码 方法一&#xff1a; this.$router.…...

视频处理之视频抽帧的python脚本

在计算机视觉研究中&#xff0c;处理视频的时候&#xff0c;往往需要将视频抽帧成图片。如果多个视频都存放在一个文件夹里&#xff0c;并且希望抽帧出来的图片&#xff0c;以一个视频对应一个文件夹的形式存放&#xff0c;可以用以下代码&#xff0c;抽帧频率可自己手动修改&a…...

【youcans 的 OpenCV 学习课】22. Haar 级联分类器

专栏地址&#xff1a;『youcans 的图像处理学习课』 文章目录&#xff1a;『youcans 的图像处理学习课 - 总目录』 【youcans 的 OpenCV 学习课】22. Haar 级联分类器 3. Haar 特征及其加速计算3.1 Haar 特征3.2 Haar 特征值的计算3.3 积分图像3.4 基于积分图像加速计算 Haar 特…...

如何避免知识盲区 《人生处处是修行》 读书笔记

如何避免知识盲区 多元化学习&#xff1a;不要只关注自己擅长的领域&#xff0c;应该尝试学习其他领域的知识&#xff0c;例如文学、艺术、科学等。 拓宽阅读&#xff1a;阅读不同领域的书籍、文章、博客等&#xff0c;可以帮助你了解更多的知识和观点。 参加培训和课程&…...

vue返回上一页自动刷新方式

再vue中&#xff0c;返回上一页时&#xff1a;如果页面是打开的状态&#xff0c;页面不会自动刷新&#xff0c;会保持着上次跳转的状态不更新&#xff1b; 原因&#xff1a;vue-router的切换不同于传统的页面切换&#xff0c;而是路由之间的切换&#xff0c;其实就是组件之间的…...

查询SERVER正在执行的SQL语句

--方法一 select * from master..sysprocesses SELECT distinct [Spid] session_Id, ecid, [Database] DB_NAME(sp.dbid), [User] nt_username, [Status] er.status, [Wait] wait_type, [Individual Query] SUBSTRING(qt.text, er.statement_start_offset / 2,…...

现代密码学--结课论文---《70年代公钥传奇》

摘要&#xff1a;在70年代之前&#xff0c;密码学主要被军方用于通信保护。密码学的主要研究也是由情报机构&#xff08;GCHQ、NSA等&#xff09;或IBM等企业运营的获得许可的实验室中进行。这时公众几乎无法获得密码学知识&#xff0c;直到由三位密码学家Hellman、Diffie和Mer…...

cf1348B phoenix and beauty(双指针滑动窗口的构造)

C 题面 Problem - 1348B - Codeforces 输出标准输出 凤凰网喜欢美丽的数组。如果一个数组中所有长度为k的子数组 的子数都有相同的总和&#xff0c;那么这个数组就是美丽的。一个数组的子数组是任何连续元素的序列。 凤凰网目前有一个数组a 的长度为n . 他想在他的数组中插入…...

一文读懂JAVA的hashCode方法:原理、实现与应用

目录 一、概述二、实现原理和重写规则三、如何重写hashCode方法3.1 Objects.hash()方法3.2 Apache HashCodeBuilder.3.3 Google Guava3.4 自定义哈希算法四、hashcode和equals的联系五、注意事项和建议5.1 注意事项5.2 建议六、总结一、概述 在Java中,每个对象都有一个hashCod…...

RocketMQ部署

一 安装mq 1.下载RocketMQ 本教程使⽤的是RocketMQ4.7.1版本&#xff0c;建议使⽤该版本进⾏之后的demo训练。 运⾏版&#xff1a;https://www.apache.org/dyn/closer.cgi?pathrocketmq/4.7.1/rocketmq-all-4.7.1-bin-release.zip 源码&#xff1a;https://www.apache.org…...

43岁程序员,投了上万份简历都已读不回,只好把年龄改成40岁,这才有了面试机会,拿到了offer!...

40多岁找工作有多难&#xff1f; 一位43岁的程序员讲述了自己找工作的经历&#xff1a; 80年&#xff0c;大专&#xff0c;目前没到43周岁&#xff0c;年前被裁&#xff0c;简历上的年龄是42岁&#xff0c;两个多月投了上万份简历&#xff0c;99.5%是已读未回。后来改变策略把简…...

MySQL分区表相关知识总结

1.创建分区表&#xff1a; create table t(col11 int null, col22 …) engineinnodb partition by hash(col33) partitions 44; create table t(col11 int null, col22 …) engineinnodb partition by range(id) (partition p0 values less than (10), partition p1 values les…...

outlook邮箱pc/mac客户端下载 含最新版

新的 Outlook for Windows or mac 为 Outlook 应用带来了最新功能、智能辅助功能和新的新式简化设计。 你可以根据自己的风格定制它&#xff0c;并使用新的 Outlook for Windows/mac 执行更多操作&#xff01; 览版&#xff0c;与我们一起开始旅程&#xff0c;并帮助我们塑造新…...

缓存雪崩、缓存穿透、缓存击穿分别是什么?如何解决?

缓存中存放的大多都是热点数据&#xff0c;目的就是从缓存中获取数据&#xff0c;而不用直接访问数据库&#xff0c;从而提高查询效率 缓存雪崩 概念 指缓存在同一时间大面积失效&#xff0c;后面的请求直接访问数据库&#xff0c;导致数据库短时间内压力过大而崩溃&#xff…...

VBA实战篇学习笔记02 Err错误处理

文章目录 专题VI 错误处理课时38 常见错误类型错误代码13 :类型不匹配错误代码91: 对象变量或者with变量未设置错误代码1004: 视具体错误类型而变化 课时39 Err错误处理On Error Resume Next :Resume语句:Resume Next语句:未知错误:Exit SubOn Error Goto 0 专题VI 错误处理 课…...

【Git】拉取代码/提交代码

1.从将本地代码放入远程仓库 (如果有分支的情况) [git checkout xx切换分支后 git add . 将本地所有改动文件新增 commit之后 git push(将代码全部提交)] 分支操作 #查看分支 git branch #创建分支 git branch test #切换分支 git checkout test #修改代码 #提交代码git ad…...

产品预览 | 系统仿真与三维专业场仿真融合——MWORKS模型降阶工具箱

1 引言 近二十年来&#xff0c;数字化技术迅猛发展&#xff0c;以美国和中国提出装备数字工程为标志&#xff0c;人类迈入全新的数字化时代。装备数字化需要对装备的运行状态和行为进行准确的模拟和预测&#xff0c;这就需要利用系统仿真技术。系统仿真技术能够综合考虑装备的…...

如何快速掌握京东自动抢购工具:面向新手的终极完整指南

如何快速掌握京东自动抢购工具&#xff1a;面向新手的终极完整指南 【免费下载链接】autobuy-jd 使用python语言的京东平台抢购脚本 项目地址: https://gitcode.com/gh_mirrors/au/autobuy-jd 还在为抢购心仪商品时手速不够快而烦恼&#xff1f;Autobuy-JD自动抢购脚本为…...

STC8A8K64S4A12单片机PWM调速实战:手把手教你搞定循迹小车的电机驱动与速度控制

STC8A8K64S4A12单片机PWM调速实战&#xff1a;从原理到电机精准控制 当你想让一个小车平稳地沿着黑线行驶&#xff0c;或者在转弯时保持优雅的姿态&#xff0c;PWM调速技术就是那个藏在幕后的魔术师。STC8A8K64S4A12这颗国产单片机内置的硬件PWM模块&#xff0c;正是实现这一切…...

5个关键功能:如何将普通鼠标打造成macOS生产力神器?

5个关键功能&#xff1a;如何将普通鼠标打造成macOS生产力神器&#xff1f; 【免费下载链接】mac-mouse-fix Mac Mouse Fix - Make Your $10 Mouse Better Than an Apple Trackpad! 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 你是否曾为macOS上的…...

Airflow Maintenance Dags:7个关键维护工作流彻底解决Airflow运维难题

Airflow Maintenance Dags&#xff1a;7个关键维护工作流彻底解决Airflow运维难题 【免费下载链接】airflow-maintenance-dags A series of DAGs/Workflows to help maintain the operation of Airflow 项目地址: https://gitcode.com/gh_mirrors/ai/airflow-maintenance-dag…...

三步解锁RPG Maker MV/MZ加密资源:新手也能快速提取游戏文件

三步解锁RPG Maker MV/MZ加密资源&#xff1a;新手也能快速提取游戏文件 【免费下载链接】RPG-Maker-MV-Decrypter You can decrypt RPG-Maker-MV Resource Files with this project ~ If you dont wanna download it, you can use the Script on my HP: 项目地址: https://g…...

数据可视化库对比:选择最适合你的工具

数据可视化库对比&#xff1a;选择最适合你的工具 前言 大家好&#xff0c;我是前端老炮儿。今天咱们来聊聊数据可视化库的选择&#xff01; 在前端开发中&#xff0c;数据可视化是一个非常重要的领域。市面上有很多优秀的可视化库&#xff0c;比如ECharts、D3.js、Chart.js、T…...

CANN-opbase-昇腾NPU算子开发的基础设施为什么这么重要

CANN-opbase-昇腾NPU算子开发的基础设施为什么这么重要 所有 CANN AOL 算子仓库的底层都依赖 opbase。它不提供任何算子实现&#xff0c;提供的是算子注册、编译、调度的基础设施。如果你要写自定义 Ascend C 算子&#xff0c;opbase 是绕不过去的第一步。 opbase 提供了什么组…...

魔兽争霸3终极优化指南:5个简单步骤让经典游戏在现代系统上完美运行

魔兽争霸3终极优化指南&#xff1a;5个简单步骤让经典游戏在现代系统上完美运行 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在Win…...

如何快速从图表图片中提取数据?WebPlotDigitizer终极使用指南

如何快速从图表图片中提取数据&#xff1f;WebPlotDigitizer终极使用指南 【免费下载链接】WebPlotDigitizer Computer vision assisted tool to extract numerical data from plot images. 项目地址: https://gitcode.com/gh_mirrors/we/WebPlotDigitizer 你是否曾面对…...

PTFE材料在多领域的创新应用与发展分析

PTFE材料在生活领域的独特贡献不粘锅技术的演变与PTFE应用不粘锅的问世大大推动了厨房烹饪的便利性&#xff0c;而PTFE材料在其中扮演了关键角色。随着科技的发展&#xff0c;我们见证了PTFE涂层技术的不断创新&#xff0c;早期的传统不粘锅被更为耐磨、不易脱落的新型PTFE涂层…...