Reputation: 4973
I want to generate ID to event that occur in my application.
The event frequency is up to the user load, so it might occur hundreds-thousand of time per second.
I can't afford using UUID.randomUUID()
because it might be problematic in performance matters - Take a look at this.
I thought of generating ID as follows:
System.currentTimeMillis() + ";" + Long.toString(_random.nextLong())
When _random
is a static java.util.Random
my class is holding.
My questions are:
Upvotes: 10
Views: 5514
Reputation: 5251
I would use a library to avoid reinventing the wheel.
For example, JUG (https://github.com/cowtowncoder/java-uuid-generator) can generate 5 millions time-based UUIDs per second (https://github.com/cowtowncoder/java-uuid-generator/blob/master/release-notes/FAQ) :
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>4.0.1</version>
</dependency>
UUID uuid = Generators.timeBasedGenerator().generate();
Upvotes: 0
Reputation: 533500
I would use the following.
final AtomicLong counter = new AtomicLong(System.currentTimeMillis() * 1000);
and
long l = counter.getAndIncrement(); // takes less than 10 nano-seconds most of the time.
This will be unique within your system and across restarts provided you average less than one million per second.
Even at this rate, the number will not overflow for some time.
class Main {
public static void main(String[] args) {
System.out.println(new java.util.Date(Long.MAX_VALUE/1000));
}
}
prints
Sun Jan 10 04:00:54 GMT 294247
EDIT: In the last 8 years I have switched to using nanosecond wall clock and memory-mapped files to ensure uniqueness across processes on the same machine. The code is available here. https://github.com/OpenHFT/Chronicle-Bytes/blob/ea/src/main/java/net/openhft/chronicle/bytes/MappedUniqueTimeProvider.java
Upvotes: 8
Reputation: 328594
I can't afford using UUID.randomUUID() because it might be problematic
And it might not. Currently, you're solving a problem that might not exist. I suggest to use an interface so you can easily swap out the generated ID but stick to this generator on which many smart people have spent a lot of time to make it right.
Your own solution might work in many cases but the corner cases are important and you will only see those after a few years of experience.
That said, combining the current time + Random
should give pretty unique IDs. But they are easy to guess and insecure.
Upvotes: 2
Reputation: 109547
UUID uuid = UUID.randomUUID();
is less than 8 times slower, after warming up, 0.015 ms versus 0.0021 ms on my PC. That would be a positive argument for UUID - for me.
Upvotes: 2
Reputation: 4411
To prevent possible collisions I would suggest you to somehow integrate users' unique ids into the generated id. You can do this either adding user id to directly to the generated id
System.currentTimeMillis() + ";" + Long.toString(_random.nextLong()) + userId
or you can use separate _random
for each user that uses the user's id as its seed.
Upvotes: 3