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

refactor and speed up _realName code #893

Merged
merged 7 commits into from
Dec 1, 2024
Merged

Conversation

mvdan
Copy link
Member

@mvdan mvdan commented Dec 1, 2024

(see commit messages - please do not squash)

This way we can edit it as regular Go code, with the help of an LSP,
and we can also test and benchmark it.
                  │     new     │
                  │   sec/op    │
    AbiRealName-8   1.026m ± 6%

                  │     new      │
                  │     B/s      │
    AbiRealName-8   351.6Ki ± 6%

                  │     new      │
                  │     B/op     │
    AbiRealName-8   5.363Ki ± 0%

                  │    new     │
                  │ allocs/op  │
    AbiRealName-8   19.00 ± 0%
                  │     old      │                new                 │
                  │    sec/op    │   sec/op     vs base               │
    AbiRealName-8   1025.9µ ± 6%   707.1µ ± 1%  -31.08% (p=0.001 n=7)

                  │     old      │                 new                 │
                  │     B/s      │     B/s       vs base               │
    AbiRealName-8   351.6Ki ± 6%   517.6Ki ± 2%  +47.22% (p=0.001 n=7)

                  │     old      │              new              │
                  │     B/op     │     B/op      vs base         │
    AbiRealName-8   5.363Ki ± 0%   5.362Ki ± 0%  ~ (p=0.178 n=7)

                  │    old     │              new              │
                  │ allocs/op  │ allocs/op   vs base           │
    AbiRealName-8   19.00 ± 0%   19.00 ± 0%  ~ (p=1.000 n=7) ¹
Iterating over a map is much more expensive than iterating over a slice,
given how it needs to work out which keys are present in each bucket
and then randomize the order in which to navigate the keys.
None of this work needs to happen when iterating over a slice.

A map would be nice if we were to actually do map lookups, but we don't.

                  │     old     │                new                 │
                  │   sec/op    │   sec/op     vs base               │
    AbiRealName-8   707.1µ ± 1%   196.7µ ± 1%  -72.17% (p=0.001 n=7)

                  │     old      │                  new                  │
                  │     B/s      │      B/s       vs base                │
    AbiRealName-8   517.6Ki ± 2%   1816.4Ki ± 1%  +250.94% (p=0.001 n=7)

                  │     old      │                new                 │
                  │     B/op     │     B/op      vs base              │
    AbiRealName-8   5.362Ki ± 0%   5.359Ki ± 0%  -0.05% (p=0.001 n=7)

                  │    old     │              new              │
                  │ allocs/op  │ allocs/op   vs base           │
    AbiRealName-8   19.00 ± 0%   19.00 ± 0%  ~ (p=1.000 n=7) ¹
@mvdan mvdan requested a review from lu4p December 1, 2024 00:41
@mvdan
Copy link
Member Author

mvdan commented Dec 1, 2024

This refactoring and benchmarking is ultimately for #892. But I was also curious how fast I could get the existing simple algorithm to be, before we jump to something fancy like that strings replacer. It turns out we could be about 5x as fast.

mvdan added 2 commits December 1, 2024 00:52
This lets us only check names up to the remaining input string length.

                  │     old     │                new                 │
                  │   sec/op    │   sec/op     vs base               │
    AbiRealName-8   196.7µ ± 1%   172.3µ ± 1%  -12.41% (p=0.001 n=7)

                  │     old      │                 new                 │
                  │     B/s      │     B/s       vs base               │
    AbiRealName-8   1.774Mi ± 1%   2.022Mi ± 0%  +13.98% (p=0.001 n=7)

                  │     old      │                new                 │
                  │     B/op     │     B/op      vs base              │
    AbiRealName-8   5.359Ki ± 0%   5.336Ki ± 0%  -0.44% (p=0.001 n=7)

                  │    old     │               new                │
                  │ allocs/op  │ allocs/op   vs base              │
    AbiRealName-8   19.00 ± 0%   18.00 ± 0%  -5.26% (p=0.001 n=7)
Use the term "original name" rather than "real name" for the code
as it is clearer that we mean the unobfuscated name.

Update the comments at the top of the file to be clearer with the
explanation of what kinds of inputs we can expect.

While here, use fmt.Appendf to simplify the generation code a bit.
Copy link
Member

@lu4p lu4p left a comment

Choose a reason for hiding this comment

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

Like that the injected code now lives in a real go file.

reflect_abi_code.go Outdated Show resolved Hide resolved
reflect_abi_patch.go Show resolved Hide resolved
As Paul Scheduikat points out, the loop already does not start
if the length of name is less than minHashLength.

                       │     old     │             new              │
                       │   sec/op    │   sec/op     vs base         │
    AbiOriginalNames-8   135.6µ ± 1%   135.5µ ± 0%  ~ (p=1.000 n=7)
@mvdan
Copy link
Member Author

mvdan commented Dec 1, 2024

I didn't rebase/squash as that would cause me silly conflicts to resolve. It seems fine to do one more commit to explain the last minute simplification.

@mvdan mvdan merged commit 8f71a50 into burrowers:master Dec 1, 2024
4 checks passed
@mvdan mvdan deleted the abi-bench branch December 2, 2024 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants