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

⚡️ Optimize address to string #1341

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

Philogy
Copy link
Contributor

@Philogy Philogy commented Feb 5, 2025

Description

Optimized address to hex string with some fancy bit operations. Has a fairly large gas trade-off ~360 bytes more by the looks of it, open questions:

  • worth the codesize trade off?
  • document how it works?

Checklist

  • Ran forge fmt?
  • Ran forge test?

@Philogy
Copy link
Contributor Author

Philogy commented Feb 5, 2025

Also not sure what's wrong with the diff ci check, showing error:

fatal: a branch named 'main' already exists

@Vectorized
Copy link
Owner

What made you think about this trick?

@Philogy
Copy link
Contributor Author

Philogy commented Feb 5, 2025

I was benchmarking and trying to optimize address checksum computation for a project of mine. I was looking at a table of hex nibble to binary to ascii-binary table and noticed that you could relatively cheaply compute:

  • bitmap of whether each nibble will be a letter or not
  • and eventually how to make a padded nibble into it's ascii representation
'0' 0000 -> 00110000
'1' 0001 -> 00110001
'2' 0010 -> 00110010
'3' 0011 -> 00110011
'4' 0100 -> 00110100
'5' 0101 -> 00110101
'6' 0110 -> 00110110
'7' 0111 -> 00110111
'8' 1000 -> 00111000
'9' 1001 -> 00111001
'a' 1010 -> 01100001
'b' 1011 -> 01100010
'c' 1100 -> 01100011
'd' 1101 -> 01100100
'e' 1110 -> 01100101
'f' 1111 -> 01100110

I noticed that a-f all have bit 4 set, but to exclude 8 & 9 you need to also check bit 2 & 3, giving you: b4 && (b3 || b2), which you can do by shifting and masking the word a couple times.

For the ascii representation I noticed it's basically:

          b8   b7   b6   b5   b4   b3   b2   b1
digit:     0    0    1    1   [       x       ]
letter:    0    1    1    0   [   8 ^ x - 1   ]

So yeah once you have the nibbles spaced out, padded and you have a bitmap of which byte will be a letter or not it's relatively easy to get the ascii representation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants