cowtowncoder / java-uuid-generator

Java Uuid Generator (JUG) is a Java library for generating all standard UUID versions (v1 - v7)
Apache License 2.0
699 stars 103 forks source link

Type 1 UUID getTimestamp() synchronization leads to performance bottleneck #71

Closed kushagraThapar closed 1 year ago

kushagraThapar commented 1 year ago

We are using type 1 UUID timestamp based generator - TimeBasedGenerator - which has getTimestamp() method which is synchronized. This is causing some performance bottleneck in our code.

https://github.com/cowtowncoder/java-uuid-generator/blob/18b8a5e8a288c87882bd2fb9a4d087a392f9035f/src/main/java/com/fasterxml/uuid/UUIDTimer.java#L240

My question is, can we instead use TimeBasedEpochGenerator and still get the same functionality (uniqueness) of TimeBasedGenerator UUID?

cowtowncoder commented 1 year ago

Typically uniqueness is guaranteed well enough by random-based generator that does not need synchronization. Alternatively you could create non-shared TimeBasedGenerator using random (bogus) MAC addresses.

But anything shared that uses timestamps must be synchronized in some way, so I don't think that'd help.

I am also bit surprised that you'd have a performance bottleneck in general as cost of generation itself is negligible. But perhaps with massive number of threads synchronization itself can become problematic. If so I'd try random-based generator; many users for some reason do not feel confident in uniqueness but statistically speaking it should be no worse than time/location based one.

kushagraThapar commented 1 year ago

Thanks @cowtowncoder for the response, got your point. And yes, it is for massive high concurrency which causes the synchronization API to be the bottleneck. We are using this constructor (which I see is also your suggestion) -

private static final TimeBasedGenerator TIME_BASED_GENERATOR =
            Generators.timeBasedGenerator(EthernetAddress.constructMulticastAddress());

Since this is leveraging the random bogus mac address way, I wonder if we can modify the source code and get rid of the synchronized from getTimestamp() method from UUIDTimer class since every other java process will have its own bogus address calculated even if they are on the same JVM or machine?

kushagraThapar commented 1 year ago

we will test the random UUID generator with performance and high throughput tests to see if it has any uniqueness issues, but for now, we can close this issue, thanks @cowtowncoder

cowtowncoder commented 1 year ago

@kushagraThapar although you could locally make whatever changes you want, I don't think there is a safe for JUG in general to remove synchronization.

But that shouldn't matter: problem with synchronization is with contention -- many threads being blocked -- if you have only one there is very little overhead. So it should not really matter if there is no real sharing.

kushagraThapar commented 1 year ago

@cowtowncoder - agreed on the synchronization in JUG and its safety to keep it there. I also noticed you recently added a lock() in Epoch Time based generator as well :) We will go ahead with random based UUID and see how that goes, thanks again!