Java: I have a problem using System.currentTimeMillis() function
i am using System.currentTimeMillis() to generate unique values in foor loop problem is loop executes too fast and System.currentTimeMillis() gives me duplicate values.
How can i generate for sure unique values.
for(int a=0;a<=10;a++){
System.out.println(System.currentTimeMillis())
}
I also tried following but it is also not generaet to generate unique number
System.currentTimeMillis()+Math.random()
why don't you use System.nanoTime() instead?
Why don't you use a UUID library to generate unique identifiers (already there in the JDK http://download.oracle.com/javase/6/docs/api/java/util/UUID.html).
Or for a more simple approach: append a static counter
I think your approach is wrong, if this is a requirement.
Theoretically, no matter how fine-grained your timer, a machine might execute it in less time than the timer's granularity. It's not correct in a technical sense to depend on this being true.
Or looking at it another way - why do you need these values to be unique (what are you using them for)? If you really want them to be a measure of the time it was executed, then you ought to be happy that two iterations that happened within the same millisecond got the same value.
Have you considered using a static, monotonous counter to assign IDs to each iteration that are unique within each execution (AtomicLong is great for this)? Something like the following is very easy and has no concurrency issues:
public class YourClass {
private static final AtomicLong COUNTER = new AtomicLong();
private static nextId() { return COUNTER.getAndIncrement(); }
// Rest of the class, which calls nextId() when it needs an identifier
}
If you need the timing info and uniqueness, then that's two separate requirements, so why not have a composite key made up of the time and an arbitrary unique ID?
The answer is obvious - get a slower computer! Well, that or use System.nanoTime as described right here on SO - System.currentTimeMillis vs System.nanoTime. But seriously, you shouldn't be using time as unique number generator unless you absolutely have to.
The problem with using the system time of course being that:
The time returned by your system
calls is rounded up to a higher
degree of precision than the actual
CPU clock time. If your ID generation
code runs faster than this degree of
precision then you will have
collision.
If your code is distributed and each
unit of work is generating ID's then
you run into the possibility of ID
collision as the separate CPU's or
CPU core's allocate ID's using their
independent clocks.
In libraries like Java that are
actually returning the system time
based off a user settable property
you run into a higher chance of
multiple ID collision anytime the
date is reset to some period in the
past, for whatever reason.
A very good alternative to generating unique identifiers is to utilize the not-so-ironically named Universally Unique Identifier. There is a multiple implementations in various languages, for Java 5 and higher you can use the UUID class.
Edit: To add some useful information about UUID.
Similar to #Andrej's solution, but combining a timer and a counter so your numbers shouldn't repeat if you restart your application.
public enum IdGenerator {
;
private static final AtomicLong COUNTER = new AtomicLong(System.currentTimeMillis()*1000);
public static long nextId() { return COUNTER.getAndIncrement(); }
}
If you want to still use your method, you could do:
for(int a=0;a<=10;a++){
Thread.sleep(1);
System.out.println(System.currentTimeMillis())
}
Explicitly making your CPU slower.
try Math.random()*System.currentTimeMillis()
here is a sample outcome
4.1140390961236145E11,
4.405289623285403E11,
6.743938910583776E11,
2.0358542930175632E11,
1.2561886548511025E12,
8.629388909268735E11,
1.158038719369676E12,
2.5899667030405692E11,
7.815373208372445E11,
1.0887553507952611E12,
3.947241572203385E11,
1.6723200316764807E11,
1.3071550541162832E12,
2.079941126415029E11,
1.304485187296599E12,
3.5889095083604164E10,
1.3230275106525027E11,
6.484641777434403E11,
5.109822261418748E11,
1.2291750972884333E12,
8.972865957307518E11,
4.022754883048088E11,
7.997154244301389E11,
1.139245696210086E12,
2.633248409945871E11,
8.699957189419155E11,
9.487098785390422E11,
1.1645067228773708E12,
1.5274939161218903E11,
4.8470112347655725E11,
8.749120668472205E11,
2.435762445513599E11,
5.62884487469596E11,
1.1412787212758718E12,
1.0724213377031631E12,
3.1388106597100226E11,
1.1405727247661633E12,
1.2464739913912961E12,
3.2771161059896655E11,
1.2102869787179648E12,
1.168806596179512E12,
5.871383012375131E11,
1.2765757372075571E12,
5.868323434343102E11,
9.887351363037219E11,
5.392282944314777E11,
1.1926033895638833E12,
6.867917070018711E11,
1.1682059242674294E12,
2.4442056772643954E11,
1.1250254537683052E12,
8.875186600355891E10,
3.46331811747409E11,
1.127077925657995E12,
7.056541627184794E11,
1.308631075052609E12,
7.7875319089675E11,
5.52717019956371E11,
7.727797813063546E11,
6.177219592063667E11,
2.9448141585070874E11,
9.617992263836586E11,
6.762500987418107E11,
1.1954995292124463E12,
1.0741763597148225E12,
1.9915919731861673E11,
9.507720563185525E11,
1.1009594810160002E12,
4.1381256571745465E11,
2.2526550777831213E11,
2.5919816802026202E11,
3.8453225321522577E11,
3.796715779825083E11,
6.512277843921505E10,
1.0483456960599313E12,
1.0725956186588704E11,
5.701504883615902E11,
9.085583903150035E11,
1.2764816439306753E12,
1.033783414053437E12,
1.188379914238302E12,
6.42733442524156E11,
3.911345432964901E11,
7.936334657654698E11,
1.4473479058272617E11,
1.2030471387183499E12,
5.900668555531211E11,
8.078992189613184E11,
1.2004364275316113E12,
1.250275098717202E12,
2.856556784847933E11,
1.9118298791320355E11,
5.4291847597892596E11,
3.9527733898520874E11,
6.384539941791654E11,
1.2812873515441786E11,
6.325269269733575E9,
5.403119000792323E11,
8.023708335126083E11,
3.761680594623883E10,
1.2641772837928888E11,
Check out UUID as well...
My suggestion
long id = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
//do your work
id++;
}
Related
I have a project where I make a request to get some objects. This is the fastest implementation I have after making some tests but I feel I'm missing something. I have 2000 objects in database for my tests and the code before the computation takes 3.25 seconds to execute.
val allSessions = realm.where(Session::class.java).isNotNull("endDate").findAll()
// added for better performances
val sessionsList = realm.copyFromRealm(allSessions)
val sessionGroup1 = mutableListOf<Session>()
val sessionGroup2 = mutableListOf<Session>()
// otherwise the bottleneck is here, the foreach is slow
sessionsList.forEach { session ->
if (session.isGroup1()) {
sessionGroup1.add(session)
} else {
sessionGroup2.add(session)
}
}
// doComputations(), like sums, averages...
I have to access values for all objects to performs sum, averages and so on.
What would be the fastest way to do that?
try making endDate field as Index field using annotation.
from documentation:
Like primary keys, this makes writes slightly slower , but makes reads faster. (It also makes your Realm file slightly larger, to store the index.) It’s best to only add indexes when you’re optimizing the read performance for specific situations.
import io.realm.annotations.Index;
#Index
private String endDate;
I'm glad to have achieved much better results using the following:
#Index does help, not by a lot in my case but still
I made a dedicated computable object as small as possible
I used RealmResults.sum() which is so fast you should absolutely consider it
I reversed the direction of a relationship to speed up queries
Currently at 0.38s while keeping a for loop in my code, otherwise basic calculations takes 0.16s, so I'm in between a 10x to 20x performance gain!
Note: I no longer use realm.copyFromRealm(allSessions)
This is not super necessary, I am just curious to see what others think. I know it is useless, it's just for fun.
Now I know how to do this, it's fairly simple. I am just trying to figure out a way to do this differently that doesn't require new variables to be created crowding up my class.
Here's how I would do it:
float timePassed = 0f;
public void update(){
timePassed += deltatime;//Deltatime is just a variable that represents the time passed from one update to another in seconds (it is a float)
if(timePassed >= 5){
//code to be ran every 5 seconds
timePassed -= 5f;
}
}
What I want to know is if there is a way to do this without the time passed variable. I have a statetime (time since loop started) variable that I use for other things that could be used for this.
If the goal really is to run code every X seconds, my first choice would be to use a util.Timer. Another option is to use a ScheduledExecutorService which adds a couple enhancements over the util.Timer (better Exception handling, for one).
I tend to avoid the Swing.Timer, as I prefer to leave the EDT (event dispatch thread) uncluttered.
Many people write a "game loop" which is closer to what you have started. A search on "game loop" will probably get you several variants, depending on whether you wish to keep a steady rate or not.
Sometimes, in situations where one doesn't want to continually test and reset, one can combine the two functions via the use of an "AND" operation. For example, if you AND 63 to an integer, you have the range 0-63 to iterate through. This works well on ranges that are a power of 2.
Depending on the structure of your calling code, you might pass in the "statetime" variable as a parameter and test if it is larger than your desired X. If you did this, I assume that a step in the called code will reset "statetime" to zero.
Another idea is to pass in a "startTime" to the update method. Then, your timer will test the difference between currentTimeMillis and startTime to see if X seconds has elapsed or not. Again, the code you call should probably set a new "startTime" as part of the process. The nice thing about this method is that there is no need to increment elapsed time.
As long as I am churning out ideas: could also create a future "targetTime" variable and test if currentTimeMillis() - targetTime > 0.
startTime or targetTime can be immutable, which often provides a slight plus, depending on how they are used.
I was under the impression that the UUID spec required a guaranteed, true, globally unique result, not unique 99.99999999999% of the time, but truly 100% of the time. From the spec:
A UUID is 128 bits long, and can guarantee
uniqueness across space and time.
It looks like java only support V3 and V4 of the UUID spec. V4 isn't truly unique. With the V3 implementation using nameUUIDFromBytes, the following results in duplicates, because the computer is too fast (edit: looping to 10 and called new Date().getTime() will produce duplicates because the computer loops faster than new Date().getTime() can produce a different value on each iteration):
String seed;
for (int i = 0; i < 10; i++) {
seed = "<hostname>" + new Date().getTime();
System.out.println(java.util.UUID.nameUUIDFromBytes(seed.getBytes()));
}
Am I mistaken in assuming that a UUID is 100% unique, and that it is only practically unique but not perfectly so? Is there anyway to do this in Java?
There are different methods of UUID generation. The kind you're using is behaving exactly as it should. You're using nameUUIDFromBytes, a "Static factory to retrieve a type 3 (name based) UUID based on the specified byte array."
This generates the same UUID if given the same name. As you've discovered, your loop is passing-in the same name every time, so you get the same UUID.
Have a look at Gabe's advice here: Which UUID version to use?
He recommends you use V4, which as others have pointed out is good enough for any realistic use case.
Because your entropy is limited to your memory, you can never ensure a UUID is "guaranteed, true, globally unique result". However, 99.99999999999% is already pretty good.
If you want to ensure unique values in your database, you could use a simple integer that's incremented to be sure it's unique. If you want to use UUIDs and be really sure they're unique, you just have to check that upon creation. If there's a duplicate, just create another one until it's unique.
Duplicates can happen, but IIRC, part of them is created dependent on your current time, so if you're just creating one every 5 minutes, you should be safe.
As others have pointed out, the type-4 UUID returned by UUID.randomUUID() is likely to be unique enough for any practical application. Cases where it's not are likely to be pathological: for example, rolling back a VM to a live snapshot, without restarting the Java process, so that the random-number generator goes back to an exact prior state.
By contrast, a type-3 or type-5 UUID is only as unique as what you put into it.
A type-1 UUID (time-based) should be very slightly "more" unique, under certain constraints. The Java platform does not include support for generating a type-1 UUID, but I've written code (possibly not published) to call a UUID generating library via JNI. It was 18 lines of C and 11 lines of Java.
I need to create a 64 bit unique integer in Java so that collision chances are low. The system is not distributed, so collisions between different computers are not a problem.
Is there any way, we can create a 64 bit integer in Java which is always Unique?
As of now I am using -
long number = System.nanoTime();
Is this the right way to generate 64 bit Unique Integer in Java or is there anything else I can try?
UPDATE:-
How about doing this way? Will this be unique?
UUID number = UUID.randomUUID();
long uniqueNumber = number.timestamp();
If you need the numbers to be unique in one process, robust between restarts, you can use a simple AtomicLong and a timer.
private static final AtomicLong TS = new AtomicLong();
public static long getUniqueTimestamp() {
long micros = System.currentTimeMillis() * 1000;
for ( ; ; ) {
long value = TS.get();
if (micros <= value)
micros = value + 1;
if (TS.compareAndSet(value, micros))
return micros;
}
}
This will give you a unique "timestamp" with a millisecond accuracy but can only handle 1000 ids per millisecond without getting ahead of the actual time. This works fine on restart as the time will jump past previous values (again assuming you have less than one million per second on average)
Use a HashSet in order to ensure uniqueness of the values you're storing. You can then check whether the insert was successful by checking what add returns. If the values have to be 'randomised' you can use your own algorithm, or check out SecureRandom.
Long getUniqueNumber(HashSet uniqueNumberSet) {
Long unique = generateUniqueNumber();
if(!uniqueNumberSet.add(unique)) { // handle collision }
return unique;
}
As Marc B said, the best approach is a simple long which is initialized with zero and incremented every time you need a new value.
If you need concurrency, or if performance is not an issue at all, then you can use AtomicLong as suggested by Loc Ha; however, if you really need it to be a long and not an int, then I suspect you are going to be generating lots of them, so you should probably avoid the extra overhead of AtomicLong unless you are sure you also need concurrency.
System.nanoTime() is not a good idea, as you have no guarantee that two consecutive calls to it will always yield different values.
EDIT (to cover update in question)
No, the timestamp part of the UUID is not guaranteed to be unique, for precisely the same reasons that System.nanoTime() is not guaranteed to be unique. If the timestamp of the UUID was unique, then there would be no need to have a UUID type, we would just always use that timestamp part. Time is always a bad way to go about guaranteeing uniqueness.
You want to get unique ID, the appropriate way(although 128 bit):
UUID.randomUUID();
A bit less appropriate(collisions* are possible) with 64 bits:
UUID.getLeastSignificantBits();
UUID.getMostSignificantBits();
To really get unique ID(if they are critical to your operation):
Use centralised storage of all IDs
When you need an ID, let this centralised system handle it -> DB and auto incremented values are usually the easiest way
*collisions => 2 or more equal values
I need to create a timestamp (in milliseconds) in Java that is guaranteed to be unique in that particular VM-instance. I.e. need some way to throttle the throughput of System.currentTimeMillis() so that it returns at most one results every ms. Any ideas on how to implement that?
This will give a time as close the current time as possible without duplicates.
private static final AtomicLong LAST_TIME_MS = new AtomicLong();
public static long uniqueCurrentTimeMS() {
long now = System.currentTimeMillis();
while(true) {
long lastTime = LAST_TIME_MS.get();
if (lastTime >= now)
now = lastTime+1;
if (LAST_TIME_MS.compareAndSet(lastTime, now))
return now;
}
}
One way to avoid the limitation of one id per milli-second is to use a micro-second timestamp. i.e. multiply currentTimeMS by 1000. This will allow 1000 ids per milli-second.
Note: if time goes backwards, eg due to an NTP correction, the time will just progress at 1 milli-second per invocation until time catches up. ;)
You can use System.nanoTime() for better accuracy
Although I tried below and each time it gives different values, it probably is not guaranteed to be unique all the time.
public static void main(String[] args) {
long time1 = System.nanoTime();
long time2 = System.nanoTime();
long time3 = System.nanoTime();
System.out.println(time1);
System.out.println(time2);
System.out.println(time3);
}
Another way is to use AtomicInteger/AtomicLong classes for unique numbers if the time is not important for you and you just need unique number, this probably is a btter choice.
While searching for a solution I came across ULIB
(Universally Unique Lexicographically Sortable Identifier)
https://github.com/huxi/sulky/tree/master/sulky-ulid/
It's not a long, but shorter then UUID.
A ULID:
Is compatible with UUID/GUID's
1.21e+24 unique ULIDs per millisecond (1,208,925,819,614,629,174,706,176 to be exact)
Lexicographically sortable
Canonically encoded as a 26 character string, as opposed to the 36 character UUID
Uses Crockford's base32 for better efficiency and readability (5 bits per character)
Case insensitive
No special characters (URL safe)
You could use System.nanoTime(), which is the most precise available system timer, and divide that by million to get milliseconds. While there are no formal guarantees on how often it's updated, I believe it's reasonable to assume that it updates way more (order(s) of magnitude) frequently than once per millisecond. Of course, if you create integer timestamps by less than millisecond interval, then they can't all be unique.
Note that the absolute value nanoTime() is arbitrary. If you want absolute time, calibrate it somehow, i.e. compare it to currentTimeMillis() when starting.
Could you perhaps make use of java.util.UUID and it's timestamp() and clockSequence()?
Method Summary
int clockSequence()
The clock sequence value associated with this UUID.
long timestamp()
The timestamp value associated with this UUID.
More details here: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html