首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >回路优化的稳健性

回路优化的稳健性
EN

Ethereum用户
提问于 2022-10-10 09:16:02
回答 3查看 270关注 0票数 0

我真的很难想出优化这段代码的方法。这能更有效率吗?

代码语言:javascript
复制
    /**
        @dev Utility function to remove a given address from a list of addresses
        @param arr A list of addresses
        @param token Address to remove
    */
    function _remove(address[] storage arr, address token) internal {
        uint len = arr.length;
        for(uint i; i < len; ++i) {
            if (arr[i] == token) {
                arr[i] = arr[arr.length - 1];
                arr.pop();
                break;
            }
        }
    }
    ```
EN

回答 3

Ethereum用户

发布于 2022-10-10 16:58:54

  • 要将len加载到内存中以节省气体,不妨在这里使用它:arr[i] = arr[len - 1];
  • 您可以取消检查++i操作,它无论如何不会溢出:{++i}

来源

除此之外,代码看起来已经相当有效了。

编辑一些人建议使用映射。首先,它实际上取决于上下文(这里我们没有这个上下文,因为数组可能为契约中的其他目的服务)。其次,solidity中的数组的行为类似于映射,尽管具有一些不同的功能。如果你感兴趣的话,你可以看到这个回答

票数 2
EN

Ethereum用户

发布于 2022-10-10 14:57:14

这种方法看起来非常好,而且效率很高,因为它似乎并不是您可以做的优化它的任何事情。

您需要从存储数组中移除元素,但首先,您需要找到它,您没有任何选择,只能先进行线性搜索才能找到它。您可能会变得更加复杂,并使用一个mapping来保存存储数组中每个token的索引,以便在下一次恒定时间内找到它,但是这会更复杂,而且仍然要花费一些。因此,您需要权衡您的选项,并计算,看看在您的情况下,采用另一种方法是否更有效。

否则,你的方法看上去是合理的。除非您实际上可以将tokens本身放入mapping中,所以如果您需要获取/删除它们,则可以在固定时间内完成。

还有一条建议:

  1. 通过进行线性搜索来查找令牌。最糟糕的情况是,令牌甚至不存在,因此从存储中读取会丢失大量的处理。如果元素位于最后一个位置,则不需要使用arr[i] = arr[arr.length - 1];“移动”它,而只需弹出它。
票数 0
EN

Ethereum用户

发布于 2022-10-10 20:11:49

我不确定这里的最终目标是什么。但是我确信for循环是一个99%的错误选择。

我强烈建议阅读可迭代映射。(如果您真的需要使用一个地址数组) https://medium.com/rayonprotocol/creating-a-smart-contract-having-iterab

票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/137191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档