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

optimizations #63

Merged
merged 11 commits into from
Jan 10, 2025
Merged

optimizations #63

merged 11 commits into from
Jan 10, 2025

Conversation

anatoly-kussul
Copy link
Contributor

@anatoly-kussul anatoly-kussul commented Jan 6, 2025

Key changes:

  • simplified encoder complexity (now only 2 cases instead of 4, one for default alphabet, other for generic)
  • changed custom alphabets encode to efficiently place runes into a byte slice backwards and avoid unnecessary allocations
  • added hashedUUID function to reduce allocation in NewWithNamespace, as google's uuid.NewSHA1 makes 4 unnecessary allocations

Benchamarks:

goos: linux
goarch: amd64
pkg: github.com/lithammer/shortuuid/v4
cpu: 12th Gen Intel(R) Core(TM) i5-12400F
                         │   v4.2.0    │                 new                 │
                         │   sec/op    │   sec/op     vs base                │
UUID-12                    123.3n ± 0%   119.6n ± 0%   -3.04% (p=0.000 n=10)
Encoding-12                44.42n ± 1%   42.32n ± 0%   -4.74% (p=0.001 n=10)
EncodingB57_MB-12          123.2n ± 4%   116.5n ± 2%   -5.36% (p=0.001 n=10)
EncodingB16-12             134.5n ± 0%   151.9n ± 0%  +12.98% (p=0.000 n=10)
EncodingB16_MB-12          327.0n ± 1%   191.2n ± 2%  -41.53% (p=0.000 n=10)
Decoding-12                173.9n ± 1%   167.4n ± 1%   -3.79% (p=0.000 n=10)
DecodingB16-12             206.0n ± 1%   200.0n ± 1%   -2.91% (p=0.000 n=10)
DecodingB16_MB-12          254.6n ± 1%   249.9n ± 2%   -1.87% (p=0.015 n=10)
NewWithAlphabet-12         387.2n ± 1%   381.0n ± 2%   -1.61% (p=0.008 n=10)
NewWithAlphabetB16-12      270.4n ± 1%   293.6n ± 1%   +8.56% (p=0.000 n=10)
NewWithAlphabetB16_MB-12   553.5n ± 0%   403.5n ± 1%  -27.10% (p=0.000 n=10)
NewWithNamespace-12        249.3n ± 1%   166.3n ± 1%  -33.29% (p=0.000 n=10)
NewWithNamespaceHttp-12    255.1n ± 3%   169.8n ± 1%  -33.43% (p=0.000 n=10)
NewWithNamespaceHttps-12   256.4n ± 2%   167.4n ± 1%  -34.73% (p=0.000 n=10)
geomean                    206.5n        177.4n       -14.08%

                         │    v4.2.0     │                 new                  │
                         │     B/op      │    B/op     vs base                  │
UUID-12                     24.00 ± 0%     24.00 ± 0%        ~ (p=1.000 n=10) ¹
Encoding-12                 24.00 ± 0%     24.00 ± 0%        ~ (p=1.000 n=10) ¹
EncodingB57_MB-12           72.00 ± 0%     80.00 ± 0%  +11.11% (p=0.000 n=10)
EncodingB16-12              64.00 ± 0%     32.00 ± 0%  -50.00% (p=0.000 n=10)
EncodingB16_MB-12          480.00 ± 0%     96.00 ± 0%  -80.00% (p=0.000 n=10)
Decoding-12                 0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
DecodingB16-12              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
DecodingB16_MB-12           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
NewWithAlphabet-12          264.0 ± 0%     264.0 ± 0%        ~ (p=1.000 n=10) ¹
NewWithAlphabetB16-12      128.00 ± 0%     96.00 ± 0%  -25.00% (p=0.000 n=10)
NewWithAlphabetB16_MB-12    544.0 ± 0%     160.0 ± 0%  -70.59% (p=0.000 n=10)
NewWithNamespace-12        200.00 ± 0%     24.00 ± 0%  -88.00% (p=0.000 n=10)
NewWithNamespaceHttp-12    208.00 ± 0%     24.00 ± 0%  -88.46% (p=0.000 n=10)
NewWithNamespaceHttps-12   224.00 ± 0%     24.00 ± 0%  -89.29% (p=0.000 n=10)
geomean                                ²               -51.82%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                         │    v4.2.0    │                 new                  │
                         │  allocs/op   │ allocs/op   vs base                  │
UUID-12                    1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=10) ¹
Encoding-12                1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=10) ¹
EncodingB57_MB-12          2.000 ± 0%     1.000 ± 0%  -50.00% (p=0.000 n=10)
EncodingB16-12             2.000 ± 0%     1.000 ± 0%  -50.00% (p=0.000 n=10)
EncodingB16_MB-12          4.000 ± 0%     1.000 ± 0%  -75.00% (p=0.000 n=10)
Decoding-12                0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
DecodingB16-12             0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
DecodingB16_MB-12          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
NewWithAlphabet-12         2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=10) ¹
NewWithAlphabetB16-12      3.000 ± 0%     2.000 ± 0%  -33.33% (p=0.000 n=10)
NewWithAlphabetB16_MB-12   5.000 ± 0%     2.000 ± 0%  -60.00% (p=0.000 n=10)
NewWithNamespace-12        5.000 ± 0%     1.000 ± 0%  -80.00% (p=0.000 n=10)
NewWithNamespaceHttp-12    5.000 ± 0%     1.000 ± 0%  -80.00% (p=0.000 n=10)
NewWithNamespaceHttps-12   5.000 ± 0%     1.000 ± 0%  -80.00% (p=0.000 n=10)
geomean                               ²               -47.13%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

@lithammer lithammer self-requested a review January 6, 2025 07:34
@anatoly-kussul anatoly-kussul mentioned this pull request Jan 9, 2025
encoder.go Outdated Show resolved Hide resolved
func hashedUUID(space uuid.UUID, data string) (u uuid.UUID) {
h := sha1.New()
h.Write(space[:]) //nolint:errcheck
h.Write(unsafe.Slice(unsafe.StringData(data), len(data))) //nolint:errcheck
Copy link
Owner

Choose a reason for hiding this comment

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

I noticed that in google/uuid#181, you're not using unsafe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, in that PR signature accepts data []byte.
unsafe here is used to read input string as a byte slice without allocating additional objects.
So if that PR is merged and released, it could then be integrated here as:
u = uuid.NewSHA1(uuid.NameSpaceDNS, unsafe.Slice(unsafe.StringData(data), len(data)))
instead of
u = uuid.NewSHA1(uuid.NameSpaceDNS, []byte(data))
as this []byte conversion sometimes adds an additional allocation.

@lithammer lithammer merged commit 9e9e14d into lithammer:master Jan 10, 2025
3 checks passed
@lithammer
Copy link
Owner

Again, thanks 🙂

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