浏览代码

Optimize removal in EnumerableSet (#2605)

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
William Morriss 4 年之前
父节点
当前提交
750a17653d
共有 2 个文件被更改,包括 11 次插入9 次删除
  1. 3 0
      CHANGELOG.md
  2. 8 9
      contracts/utils/structs/EnumerableSet.sol

+ 3 - 0
CHANGELOG.md

@@ -1,5 +1,8 @@
 # Changelog
 
+## Unreleased
+ * Enumerables: Improve gas cost of removal in `EnumerableSet` and `EnumerableMap`.
+
 ## Unreleased
 
  * `IERC20Metadata`: add a new extended interface that includes the optional `name()`, `symbol()` and `decimals()` functions. ([#2561](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2561))

+ 8 - 9
contracts/utils/structs/EnumerableSet.sol

@@ -81,15 +81,14 @@ library EnumerableSet {
             uint256 toDeleteIndex = valueIndex - 1;
             uint256 lastIndex = set._values.length - 1;
 
-            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
-            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
-
-            bytes32 lastvalue = set._values[lastIndex];
-
-            // Move the last value to the index where the value to delete is
-            set._values[toDeleteIndex] = lastvalue;
-            // Update the index for the moved value
-            set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
+            if (lastIndex != toDeleteIndex) {
+                bytes32 lastvalue = set._values[lastIndex];
+
+                // Move the last value to the index where the value to delete is
+                set._values[toDeleteIndex] = lastvalue;
+                // Update the index for the moved value
+                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
+            }
 
             // Delete the slot where the moved value was stored
             set._values.pop();