Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

java - Why is System.nanoTime() returning such a large number, when that much time has not been elapsed?

So I'm pretty new at Java, but I'm making a text adventure game for CompSci, and this is my code for levels.

public static int level(int exp, Long time, int levelnum) {
  //Time is the time elapsed since the program started
    time = System.nanoTime();
    //I divi  de by 10,000,000 twice because that sqared is 100 trillion, the conversion factor between nano and second
   exp = (int)(Math.round(time/10000000));
   exp = Math.round(exp/10000000);
    //The exp, or experience, is the percent, under 100, of the way to the next level. 1 is 10%, 2 is 20, etc.
    while (exp > 10){
        //This loop will check to make sure exp is under 10. If not, it will add one to the level number, and then subtract 10 from the exp and check again.
        levelnum++;
        exp = exp - 10;
    } 
    
   int bar;
   bar =1; 
   //Bar is here because originally, I planned on this all being one method, the next one and this, and so I placed it in meaning for it to act as the return value. It has stayed the return value.
   System.out.println(levelnum + "
" + exp + "
" + time);
   //That was for debugging purposes, so I could see the levels data as it processed.
   progBar(levelnum, exp);
    return bar;

    
}
public static void progBar(int levelnum, int exp){
    char barOpen, barClose;
    String bar = "";
    String emptyBar;
    //I realize now that I could have just "[" + bar + "]", but at the time i didnt think of that
    barOpen = '[';
    barClose = ']'; 
    if (exp > 1){
        //ok so if the experience is greater than 1, then we repeat the = that many times. That way, we don't repeat it when we have one
    bar = "=".repeat(exp);
    }else if (exp <= 1){
    bar = "=";
    }
    //This makes sure we have the adequate space between the experience and the bar close
    emptyBar = " ".repeat(10-exp);
    System.out.println("You are currently level " + levelnum + "
" + barOpen + bar + emptyBar + barClose);
     
}

When I ran this yesterday, it succeeded in the level barring. However, today System.nanoTime() has begun to give extremely large numbers, even in different machines, none of which accurately represent the time which has elapsed. How could I fix this?

question from:https://stackoverflow.com/questions/65896593/why-is-system-nanotime-returning-such-a-large-number-when-that-much-time-has

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

tl;dr

The only meaning you should assign to System.nanoTime is to call it twice and compare the two values as an approximate number of elapsed nanoseconds. Do not interpret the two values as being anything other than as minuend and subtrahend (the two parts of a subtraction operation) for elapsed nanos.

Duration.ofNanos( System.nanoTime() - start )

Large or small nanoTime is irrelevant

Read the documentation:

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative).

The number returned by this method has no meaning other than to be compared to another such returned value to track elapsed time on a scale of nanoseconds.

So whether the number returned is large or small is irrelevant. Comparing the returned numbers between computers or JVMs is meaningless.

In my experience, the numbers may be a count of nanoseconds since the host machine was booted. But you should never count on that. Such a fact is but a mere implementation detail. That detail may differ between Java implementations, or between host OSes.

Also, keep in mind that your computer hardware is not likely able to track time precisely by single nanoseconds. So elapsed time will be approximate.

The number returned represents nanoseconds. That means a billionth of a second. So your math is invalid.

Duration

Java offers you a class to track a span of time unattached to the timeline on a scale of nanoseconds: Duration. So no need for you to do any math.

long start = System.nanoTime() ;
…
Duration duration = Duration.ofNanos( System.nanoTime() - start ) ;
String report = duration.toString() ;

You may interrogate for the amount of elapsed time by calling the various to… methods.

Tips:

  • If doing benchmarking, consider using the jmh library.
  • If doing regular business-style apps, use java.time.Instant class to capture moments.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...