javamultithreadingtime-estimation

Java Thread getting elapsed time :: how to get small change


Here is my run for method for thread

public void run() {
    float timeElapsed =0;
    while(running){
        time += timeElapsed; // recording time.
        if(timeElapsed != 0 )Log.d(id, "pressed time " + time + " "+ timeElapsed);
/**fromhere :: just how I get fps ratio.
        oneSec += timeElapsed;
        fpsCompound++;
        if(oneSec > 1){
            fpsCompound = 0;
            oneSec = 0;
        }
**/endhere 
        timeBefore = System.nanoTime();
        loopCall(timeElapsed);
        timeElapsed =(System.nanoTime()-timeBefore)/1000000000;
//sometimes my timeElapsed is 0, my guess is because the loopCall does nothing in some cases
        while(timeElapsed < .005){
            timeElapsed =(System.nanoTime()-timeBefore)/1000000000;
        }
    }
}

I want to get rid of that while loop that delays the loop if timeElapsed is less than .005.

However if I skip that delay portion, I sometimes get my timeElapsed as 0 even though there has to be a tiny portion of seconds passed.

Accumulated result of these zero elapsed time results in unexpected time error. So I delay my thread if each loop is too fast to record the time.

This unnecessary delay seems pretty stupid. There must be a correct way to calculate the time.

EDIT:

It seems that dividing timeElapsed by 1000000000 returns value that's too small for my float to contain. Is there a way to contain such a small number?


Solution

  • I think you should keep nanoseconds as long and not convert it into float seconds.

    then you'll have code like this: timeElapsed is defined as long:

                long timeElapsed = 0;
    

    End of your loop will look like this:

                timeBefore = System.nanoTime();
                loopCall(timeElapsed);
                timeElapsed =(System.nanoTime()-timeBefore);        
                while(timeElapsed < 5000000){
                    timeElapsed = (System.nanoTime()-timeBefore);
                }
    

    I hope that's what you're looking for.


    Also I'd recommend to do waiting with Thread.sleep(long, int); You'll lose some precision (it sleeps for milliseconds) but will save some CPU time

             /*while(timeElapsed < 5000000){
                  timeElapsed = (System.nanoTime()-timeBefore);
               }*/
    
    
               long leftToSleep = 5000000 - timeElapsed;
               if(leftToSleep > 0) {
                  //dont forget to surround it with try catch
                  Thread.sleep(leftToSleep / 1000000, (int) leftToSleep % 1000000);
               }