前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gas 优化:Solidity 中的使用动态值数组

Gas 优化:Solidity 中的使用动态值数组

作者头像
Tiny熊
发布2021-12-13 14:39:49
3.3K0
发布2021-12-13 14:39:49
举报
文章被收录于专栏:深入浅出区块链技术
  • 译文出自:登链翻译计划[1]
  • 译者:aisiji[2]
  • 校对:Tiny 熊[3]

在 Solidity 中,动态值数组是否比引用数组效率更高吗?

Photo by Nick Kwan[4] on Unsplash[5]

背景

在 Datona 实验室的 Solidity 智能数据访问合约(S-DAC)模板的开发和测试过程中,我们经常需要处理一些像用户ID这样数据小但未知长度的数据。理想情况下,这些数据存储在一个小数值的动态值数组中。

在这篇文章的例子中,我们研究了在 Solidity 中使用动态值数组是否比引用数组或类似解决方案在处理这些小数值时更高效。

讨论

当我们有一个由已知的小数值的小数组(长度小)组成的数据时,我们可以在 Solidity 中使用一个数值数组(Value Arrays),在这篇文章[6]中,我们提供并测量了 Solidity 数值数组。得出的结论是,在多数情况下使用数值数组都可以减少存储空间和gas消耗。

得出这个结论是因为Solidity在以太坊虚拟机(EVM)上运行时有 非常大的256位(32字节)机器字长[7]。基于这个特点,再加上处理引用数组时的高gas消耗,让我们考虑使用数值数组。

既然我们可以为固定值数组操作提供自己的库,同样是否也适用于动态值数组呢?

让我们比较一下动态值数组与固定长度值数组以及 Solidity 自己的固定长度数组和动态数组。

我们也将比较两个结构体,一个结构体包含一个数组长度和一个固定数组,另一个结构体包含一个数值数组。

可能的动态值数组

在 Solidity 中,只有 storage 类型有动态数组。memory 类型的数组必须有固定长度,并且不允许使用push()来附加元素。

我们以 Solidity 库形式为动态值数组提供代码,我们能提供push()(和pop())同时用于 storagememory 数组。

动态值数组需要记录并操作数组的当前长度。在下面的代码中,我们将数组长度在存储在256位(32字节)机器码值的最高位。

动态值数组

下面是一些与 Solidity 可用类型匹配的动态值数组:

代码语言:javascript
复制
Dynamic Value Arrays(动态值数组)

Type           Type Name   Description

uint128[](1 "")   uint128d1   one 128bit element value
uint64[](3 "")    uint64d3    three 64bit element values
uint32[](7 "")    uint32d7    seven 32bit element values
uint16[](15 "")   uint16d15   fifteen 16bit element values
uint8[](31 "")    uint8d31    thirty-one 8bit element values

上述我提出的类型名称,它们在会本文中使用,但你可能会有一个更好的命名方式。

下面我们将详细地研究uint8d31

更多动态值数组

很明显,有更多可能的数值数组。假设我们保留最高位的256位来存最大的动态数组长度,X(位数的值)乘以Y(元素个数)必须小于或者等于256减去容纳数组长度的位数(L):

代码语言:javascript
复制
More Dynamic Value Arrays

Type           Type Name  Len  Description

uintX[](Y "")     uintXdY     L   X * Y <= 256 - L
uint255[](1 "")   uint255d1   1   one 248bit element value
uint126[](2 "")   uint126a2   2   two 124bit element values
uint84[](3 "")    uint84d3    2   three 82bit element values
uint63[](4 "")    uint63d4    3   four 62bit element values
uint50[](5 "")    uint50d5    3   five 51bit element values
uint42[](6 "")    uint42d6    3   six 42bit element values
uint36[](7 "")    uint36d7    3   seven 36bit element values
uint31[](8 "")    uint31d8    4   eight 31bit element values
uint28[](9 "")    uint28d9    4   nine 28bit element values
uint25[](10 "")   uint25d10   4   ten 25bit element values
uint22[](11 "")   uint22d11   4   eleven 22bit element values
uint21[](12 "")   uint21d12   4   twelve 21bit element values
uint19[](13 "")   uint19d13   4   thirteen 19bit element values
uint18[](14 "")   uint18d14   4   fourteen 18bit element values
uint16[](15 "")   uint16d15   4   as above
uint15[](16 "")   uint15d16   5   sixteen 15bit element values
uint14[](17 "")   uint14d17   5   seventeen 14bit element values
uint13[](19 "")   uint13d19   5   nineteen 13bit element values
uint12[](20 "")   uint12d20   5   twenty 12bit element values
uint11[](22 "")   uint11d22   5   twenty-two 11bit element values
uint10[](25 "")   uint10d25   5   twenty-five 10bit element values
uint9[](27 "")    uint9d27    5   twenty-seven 9bit element values
uint8[](31 "")    uint8d31    5   as above
uint7[](35 "")    uint7d35    6   thirty-five 7bit element values
uint6[](41 "")    uint6d41    6   forty-one 6bit element values
uint5[](50 "")    uint5d50    6   fifty 5bit element values
uint4[](62 "")    uint4d62    6   sixty-two 4bit element values
uint3[](83 "")    uint3d83    7   eighty-three 3bit element values
uint2[](124 "")   uint2d124   7   one-hundred & twenty-four 2bit EVs
uint1[](248 "")   uint1d248   8   two-hundred & forty-eight 1bit EVs

不同的项目需要特定的数组类型,并且同一个项目可能需要多种数组类型。例如,uint8d31用于用户ID,uint5d50用于用户角色。

注意uint1d248数值数组。它让我们可以有效地将多达248个1位的元素(代表布尔值)编码到1个 EVM 字中。而Solidity相同作用的 bool[248] ,在内存中消耗多 248 倍的空间,在存储(storage)中则多8倍。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 讨论
  • 可能的动态值数组
  • 动态值数组
  • 更多动态值数组
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档