Skip to content

uuid: performance (random generators, allocations, etc) #78639

Description

@rabbbit

Proposal Details

Ref #62026 (not sure how to make this a sub-issue).

Apologies for being late or perhaps missing the earlier discussion. I didn't findmentions of "performance", "io.Reader", "efficiency", "cost", as well as the API mentioned below in #62026.

We have recently (over the last few weeks) run a performance analysis of uuid at my workplace, and we found that UUIDs can be surprisingly expensive. We mostly use gofrs and google versions. In particular:

New()

Around 25% of the cost was attributed to New UUID, or rather random data generation.

This is mitigatable in both packages we use:

Copying from local benchmarks as an indication

BenchmarkNewV4/Gofrs_NewV4-48                    1323788               902.5 ns/op            16 B/op          1 allocs/op
BenchmarkNewV4/Google_NewRandom-48               1307914               918.3 ns/op            16 B/op          1 allocs/op
BenchmarkNewV4/Google_NewRandom_WithPool-48     10306299               115.6 ns/op             0 B/op          0 allocs/op
BenchmarkNewV4/Pborman_NewRandom-48              1273472               937.6 ns/op            16 B/op          1 allocs/op

We also tested this briefly with

BenchmarkUUIDPooledGeneration/CryptoRand-48                     32500659                36.99 ns/op            0 B/op         0 allocs/op
BenchmarkUUIDPooledGeneration/MathRandChaCha8-48                82932555                13.41 ns/op 

We also planned to experiment with thread-local random generator, but we didn't get to it yet.

Which brings questions:

  • Is the performance benefit worth complicating the stdlib version?
  • Does the API take a stance on new uuid generation (is it guaranteed to be "secure"), or is pooling allowed? Should this be specified?

parsing invalid uuid

Could the new Parse() API guarantee no allocations? This was surprisingly impactful.

This was recently improved in gofrs/uuid#241

Antipatterns - Unnecessary strings

We see quite a lot of uuid1.String() == uuid2.String(), including in loops, as well as myMap[uuid.String()] = user.

I'm not sure what's the best place to catch these today (go vet? gopls?) but could the proposal be extended to support catching obvious problems like the first one, or would that be a separate proposal?

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions