Skip to content
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

feat: adds a few more tips #1

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3afa909
✨ Add a few more tips
devtooligan Dec 14, 2021
0d796cb
docs: update descriptions and formatting
devtooligan Dec 15, 2021
5b1cad0
dapp init GolfCourse
devtooligan Dec 18, 2021
244182e
dapp install ds-test
devtooligan Dec 18, 2021
fc1882b
feat: adds examples and tests
devtooligan Dec 18, 2021
889b45f
docs: update readme.md with links and gas
devtooligan Dec 18, 2021
fb1f401
feat: work on formatting and add a bunch of examples
devtooligan Feb 13, 2022
48b3b6e
fix: typo
devtooligan Feb 14, 2022
d33debe
feat: update comments
devtooligan Feb 16, 2022
b814df2
feat: add RequireNeZero tip
devtooligan Feb 16, 2022
f45ed35
tweak: update gitignore
devtooligan Feb 16, 2022
70d07b7
fix: update directory structure to eliminate differences in contract …
devtooligan Feb 16, 2022
5606811
fix: update gas usage from new ctrct names
devtooligan Feb 16, 2022
52b02b0
fix: update links in readme
devtooligan Feb 16, 2022
00d2a4f
feat: add payable functions tip
devtooligan Feb 16, 2022
c4cfffb
fix: format code in markdown
ZeroEkkusu Feb 16, 2022
fc0707f
docs: add more info to "Make functions `payable`"
ZeroEkkusu Feb 16, 2022
d4dabe3
Merge pull request #4 from ZeroEkkusu/work-1
devtooligan Feb 16, 2022
da9e4de
fix: add tests
devtooligan Feb 17, 2022
bfac3ce
Merge branch 'some-tips-to-start' of github.com:Rari-Capital/golf-cou…
devtooligan Feb 17, 2022
964c888
docs: update explanation
devtooligan Feb 17, 2022
7b32928
feat: new tip re: array +=
devtooligan Feb 17, 2022
6bb2a4a
feat: ArayPlus contracts
devtooligan Feb 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sol linguist-language=Solidity
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/out
3 changes: 3 additions & 0 deletions .gitmodules
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
4 changes: 4 additions & 0 deletions Makefile
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
77 changes: 70 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,84 @@
# 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:
uint256 two = 4 / 2;

/// 🚀 Optimized:
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]()


- - - -

### 2. Use `>=` and `<=` instead of `>` and `<` ###
```solidity
/// 🤦 Unoptimized:
if (someInteger > 0) {
emit GreaterThanZero()
};

/// 🚀 Optimized:
if (someInteger >= 1) {
emit GreaterThanZero()
};
```

`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]()

- - - -

### 3. Using `!=` is usually cheaper than `>` or `<` ###
```solidity
// Unoptimized:
uint256 two = 4 / 2;
/// 🤦 Unoptimized:
if (bytesCount < 32) {
emit NotThirtyTwo();
}

// Optimized:
uint256 two = 4 >> 1;
/// 🚀 Optimized:
if (bytesCount != 32) {
emit NotThirtyTwo();
}
```
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]()



- - - -

### 4. Use `<address>.code.length` instead of assembly `extcodesize` to avoid variable overhead ###
```solidity
/// 🤦 Unoptimized:
uint256 size;
assembly {
size := extcodesize(someAddress)
}
return size;

/// 🚀 Optimized:
return bar.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]()

- - - -

## Myths
# Myths
1 change: 1 addition & 0 deletions lib/ds-test
Submodule ds-test added at 0a5da5
66 changes: 66 additions & 0 deletions src/GolfCourse.sol
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 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now I've put all these tests in one contract in one file, but I believe you would like to do one contract/file per example - please confirm

function unoptimizedDivideByTwo() external pure returns (uint256 two) {
Copy link
Collaborator Author

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 the function naming? we could also consider a numbering system

/// 🤦 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;
}

}
44 changes: 44 additions & 0 deletions src/GolfCourse.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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 {
/// 🤦 Unoptimized
assertEq(course.unoptimizedDivideByTwo(), 2);
}
function testOptimizedDivideByTwo() public {
assertEq(course.optimizedDivideByTwo(), 2);
}
function testOptimizedPreferGteLteOverGtLt() public {
assertTrue(course.optimizedPreferGteLteOverGtLt());
}

function testUnoptimizedPreferGteLteOverGtLt() public {
assertTrue(course.unoptimizedPreferGteLteOverGtLt());
}
function testOptimizedUseCodeLength() public {
assertTrue(course.optimizedUseCodeLength() > 0);
}

function testUnoptimizedUseCodeLength() public {
assertTrue(course.unoptimizedUseCodeLength() > 0);
}
function testOptimizedPreferNotEqualOverGtLt() public {
assertTrue(course.optimizedPreferNotEqualOverGtLt());
}

function testUnoptimizedPreferNotEqualOverGtLt() public {
assertTrue(course.unoptimizedPreferNotEqualOverGtLt());
}

}