-
Notifications
You must be signed in to change notification settings - Fork 15
feat: adds a few more tips #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
3afa909
0d796cb
5b1cad0
244182e
fc1882b
889b45f
fb1f401
48b3b6e
d33debe
b814df2
f45ed35
70d07b7
5606811
52b02b0
00d2a4f
c4cfffb
fc0707f
d4dabe3
da9e4de
bfac3ce
964c888
7b32928
6bb2a4a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| *.sol linguist-language=Solidity |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /out |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| [submodule "lib/ds-test"] | ||
| path = lib/ds-test | ||
| url = https://github.com/dapphub/ds-test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| all :; dapp build | ||
| clean :; dapp clean | ||
| test :; dapp test | ||
| deploy :; dapp create GolfCourse |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,77 @@ | ||
| # golf-course | ||
| A list of common Solidity optimization tips and myths. | ||
|
|
||
| ## Tips | ||
| # Tips | ||
|
|
||
| ### Right Shift Instead of Dividing By 2 | ||
| - - - - | ||
| ### 1. When dividing by two, use `>> 1` instead of `/ 2` ### | ||
|
|
||
| ```solidity | ||
| /// 🤦 Unoptimized (gas: 1401) | ||
| uint256 two = 4 / 2; | ||
| /// 🚀 Optimized (gas: 1372) | ||
| uint256 two = 4 >> 1; | ||
| ``` | ||
|
|
||
| The `SHR` opcode is 3 gas cheaper than `DIV` and also bypasses Solidity's division by 0 prevention overhead. | ||
| - [Gas Usage]() | ||
| - [Full Example](https://github.com/Rari-Capital/golf-course/blob/fc1882bacfec50787d9e9435d59fed4a9091fb21/src/GolfCourse.t.sol#L15) | ||
|
||
|
|
||
|
|
||
| - - - - | ||
|
|
||
| ### 2. Use `>=` and `<=` instead of `>` and `<` ### | ||
| ```solidity | ||
| /// 🤦 Unoptimized (gas: 1401) | ||
| bool positive = 1 > 0; | ||
| /// 🚀 Optimized (gas: 1337) | ||
| bool positive = 1 >= 1; | ||
| ``` | ||
|
|
||
| `if (x >= y) {}` is algebraically equivalent to !(x < y) which gets compiled to `LT .. JUMPI` which is more efficient than `x > y` which contains an extra `ISZERO` | ||
|
|
||
| - [Gas Usage]() | ||
| - [Full Example](https://github.com/Rari-Capital/golf-course/blob/fc1882bacfec50787d9e9435d59fed4a9091fb21/src/GolfCourse.t.sol#L23) | ||
|
|
||
| - - - - | ||
|
|
||
| ### 3. Using `!=` is usually cheaper than `>` or `<` ### | ||
| ```solidity | ||
| /// 🤦 Unoptimized (gas: 1423) | ||
|
||
| notThirtyTwo = 31 < 32; | ||
| /// 🚀 Optimized (gas: 1426) | ||
| notThirtyTwo = 31 != 32; | ||
| ``` | ||
| Similar to `>=` and `<=` - the `!=` gets compiled without an extra ISZERO in many cases (One notable exception being `x != 0` gets compiled the same as `x > 0`) | ||
|
|
||
| - [Gas Usage]() | ||
| - [Full Example]() | ||
| - [Full Example](https://github.com/Rari-Capital/golf-course/blob/fc1882bacfec50787d9e9435d59fed4a9091fb21/src/GolfCourse.t.sol#L31) | ||
|
|
||
|
|
||
|
|
||
| - - - - | ||
|
|
||
| ### 4. Use `<address>.code.length` instead of assembly `extcodesize` to avoid variable overhead ### | ||
| ```solidity | ||
| // Unoptimized: | ||
| uint256 two = 4 / 2; | ||
| /// 🤦 Unoptimized (gas: 1535) | ||
|
||
| uint256 size; | ||
| address address_ = address(this); | ||
| assembly { | ||
| size := extcodesize(address_) | ||
| } | ||
| return size; | ||
| // Optimized: | ||
| uint256 two = 4 >> 1; | ||
| /// 🚀 Optimized (gas: 1582) | ||
| return address(this).code.length; | ||
| ``` | ||
| Solidity [0.8.1](https:///github.com/ethereum/solidity/blob/develop/Changelog.md#081-2021-01-27) implemented `<address>.code.length` so the assembly is no longer needed | ||
|
|
||
| - [Gas Usage]() | ||
| - [Full Example](https://github.com/Rari-Capital/golf-course/blob/fc1882bacfec50787d9e9435d59fed4a9091fb21/src/GolfCourse.t.sol#L39) | ||
|
|
||
| - - - - | ||
|
|
||
| ## Myths | ||
| # Myths | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
| pragma solidity ^0.8.6; | ||
|
|
||
| contract GolfCourse { | ||
|
||
| function unoptimizedDivideByTwo() external pure returns (uint256 two) { | ||
|
||
| /// 🤦 Unoptimized | ||
| two = 4 / 2; | ||
| } | ||
|
|
||
| function optimizedDivideByTwo() external pure returns (uint256 two) { | ||
| /// 🚀 Optimized | ||
| two = 4 >> 1; | ||
| } | ||
|
|
||
| function unoptimizedPreferGteLteOverGtLt() | ||
| external | ||
| pure | ||
| returns (bool positive) | ||
| { | ||
| /// 🤦 Unoptimized | ||
| positive = 1 > 0; | ||
| } | ||
|
|
||
| function optimizedPreferGteLteOverGtLt() | ||
| external | ||
| pure | ||
| returns (bool positive) | ||
| { | ||
| /// 🚀 Optimized | ||
| positive = 1 >= 1; | ||
| } | ||
|
|
||
| function unoptimizedUseCodeLength() external view returns (uint256) { | ||
| /// 🤦 Unoptimized | ||
| address address_ = address(this); | ||
| uint256 size; | ||
| assembly { | ||
| size := extcodesize(address_) | ||
| } | ||
| return size; | ||
| } | ||
|
|
||
| function optimizedUseCodeLength() external view returns (uint256) { | ||
| /// 🚀 Optimized | ||
| return address(this).code.length; | ||
| } | ||
|
|
||
| function unoptimizedPreferNotEqualOverGtLt() | ||
| external | ||
| pure | ||
| returns (bool notThirtyTwo) | ||
| { | ||
| /// 🤦 Unoptimized | ||
| notThirtyTwo = 31 < 32; | ||
| } | ||
|
|
||
| function optimizedPreferNotEqualOverGtLt() | ||
| external | ||
| pure | ||
| returns (bool notThirtyTwo) | ||
| { | ||
| /// 🚀 Optimized | ||
| notThirtyTwo = 31 != 32; | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
| pragma solidity ^0.8.6; | ||
|
|
||
| import "ds-test/test.sol"; | ||
|
|
||
| import "./GolfCourse.sol"; | ||
|
|
||
| contract GolfCourseTest is DSTest { | ||
| GolfCourse course; | ||
|
|
||
| function setUp() public { | ||
| course = new GolfCourse(); | ||
| } | ||
|
|
||
| function testUnoptimizedDivideByTwo() public { | ||
| assertEq(course.unoptimizedDivideByTwo(), 2); | ||
| } | ||
|
|
||
| function testOptimizedDivideByTwo() public { | ||
| assertEq(course.optimizedDivideByTwo(), 2); | ||
| } | ||
|
|
||
| function testUnoptimizedPreferGteLteOverGtLt() public { | ||
| assertTrue(course.unoptimizedPreferGteLteOverGtLt()); | ||
| } | ||
|
|
||
| function testOptimizedPreferGteLteOverGtLt() public { | ||
| assertTrue(course.optimizedPreferGteLteOverGtLt()); | ||
| } | ||
|
|
||
| function testUnoptimizedPreferNotEqualOverGtLt() public { | ||
| assertTrue(course.unoptimizedPreferNotEqualOverGtLt()); | ||
| } | ||
|
|
||
| function testOptimizedPreferNotEqualOverGtLt() public { | ||
| assertTrue(course.optimizedPreferNotEqualOverGtLt()); | ||
| } | ||
|
|
||
| function testUnoptimizedUseCodeLength() public { | ||
| assertTrue(course.unoptimizedUseCodeLength() > 0); | ||
| } | ||
|
|
||
| function testOptimizedUseCodeLength() public { | ||
| assertTrue(course.optimizedUseCodeLength() > 0); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think of showing the gas from the test in the comment here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love it, tho may get hard to maintain after sol upgrades etc...