1

Let's say, we have a simple digital clock. To "power" it, we use a routine executed every second. We update seconds part in it. But, what about minutes and hours part?

What is better / more professional / offers better performance:

  1. Ignore all checking and update hour, minute and seconds part each time, every second.

  2. Use if + a variable for checking, if 60 (or 3600) seconds passed and update minute / hour part only at that precise moments.

This leads us to a question, what is better -- unnecessary drawings (first approach) or extra ifs?

I've just spotted a Javascript digital clock, one of millions similar on one of billions pages. And I noticed that all three parts (hours, minutes and seconds) are updated every second, though first changes its value only once per 3600 seconds and second once per 60 seconds.

I'm not to experienced developer, so I might me wrong. But everything, what I've learnt up until now, tells me, that if are far better then executing drawing / refreshing sequences only to draw the same content.

4
  • Are you talking about a HTML page with a <p>HH:mm:ss</p> which is updated from a setTimeout'd callback?
    – user7043
    Commented Nov 9, 2013 at 20:37
  • I would think the browser would do the important if checking. Commented Nov 10, 2013 at 3:54
  • @delnan Yes, precisely! :]
    – trejder
    Commented Nov 12, 2013 at 8:25
  • @AmyBlankenship Nope, it does not. A simple way to check it, is to select minute or hour part with your mouse (just as you select any other part of webpage's text for i.e. copying). You'll see, that after each second your selection is removed (field has been updated, even though its value hasn't changed), if developer itself doesn't introduce any if checking.
    – trejder
    Commented Nov 12, 2013 at 8:26

3 Answers 3

4
  1. Consider drift, as Mason Wheeler mentioned. Do not increment each counter, rather update the clock state directly.

    Do not assume that every minute has 60 seconds. Some have 59, others 61. If you do naive datetime math, you will also stumble over timezone and daylight saving time issues, or create new Y2K Y2038 bugs. Most languages have solid datetime libraries, use them instead to determine what time it actually is.

  2. Updating three clock hands isn't necessarily significantly more expensive than updating one. If updates are expensive, one would usually draw to an off-screen buffer and update once (often, this technique also makes for smoother animations). Note: updating ≠ drawing.

    Consider also that each update may cause a re-draw of the whole image. If the moved clock hand covered part of another, then the hand below will have to be re-drawn anyway. If multiple layers are composited over another, then your code may not realize this, but a redraw will still take place: the final image is (presumably) just a buffer of bytes.

All in all, I am vehemently opposed against trying to save a few cycles by taking the wrong shortcuts. Yes, a good programmer will try to write efficient code, but this is a wonderful example how premature optimization can be evil.

So if and only if it is valid to take the shortcut of only drawing updates when necessary, then by all means please do so. Otherwise, use the presumably inefficient variant (conjecture: it isn't that bad), or find other ways to optimize.

1
  • Thank you for providing great answer and reminding me, what I know quite well, only in different version: "Premature optimization is the beginning of all hell!" :]
    – trejder
    Commented Nov 12, 2013 at 8:33
10

Efficiency is important, but accuracy is even more important. This is why a good JavaScript clock will do exactly what you're describing.

It works something like this:

function update_clock
  Update current time (completely)
  set a timer to come back 1 second later and call update_clock

This may seem like overkill, but remember that the timers are not 100% accurate. If it comes back 1.01 seconds later instead of 1 second later, your clock can start to drift, which means simply adding 1 to the seconds value isn't good enough. Also, this way it can be done with only one timer, instead of needing two or three.

Also, let's say someone is viewing a webpage, and then they put the system to sleep for a few hours and start it back up. If your clock script resynchronizes correctly every second, this won't cause any glitches; the clock will just resynchronize against the system clock. Fancier attempts might well get screwed up by this.

Remember, correctness is almost always more important than efficiency, especially when it's not actually causing a performance bottleneck in your code.

5
  • Would the downvoter care to comment? Commented Nov 9, 2013 at 21:59
  • 3
    I wish I could understand/explain the new developer's fascination with micro-optimization questions, like, "which is faster, for or while?" They're just weird questions to experienced developers, but I can't remember if I ever thought that way or not, so I don't know how empathize. An ability to understand what the OP is really thinking when they ask these silly questions would probably be a big help in explaining why the correct answer is (almost always) "mu". Of course correctness is more important than efficiency, so why don't new developers think that way? Anyway, good answer. +1
    – Wayne
    Commented Nov 10, 2013 at 6:34
  • @MasonWheeler Thank you for your professional and enlightening answer. Seems, that I was totally wrong. Thank you for fixing my thinking.
    – trejder
    Commented Nov 12, 2013 at 8:29
  • 1
    @lwburk Congratulations on using words like "silly questions" and other hard-and-nearly-offensive language, while having only 101 rep in the very same time. I could say quite the same to all those "experienced developers" (like you?), that simply forgot, that once upon a time, long, long time ago, they're also newbies asking only silly, if not stupid questions.
    – trejder
    Commented Nov 12, 2013 at 8:32
  • 1
    @trejder - As I suggested in my post, we're all susceptible to these sorts of mistakes. Understanding why we make them is what's important. If I'm attacking anything, it's our broken human brains, collectively. I don't have any opinion about your brain, specifically.
    – Wayne
    Commented Nov 13, 2013 at 0:04
1
doTick() {
    second++;
    if ( (second % 60) == 0 ) {
        minute++;
        second = 0;
        if ( (minute % 60) == 0 ) {
            hour++;
            minute = 0;
            if ( (hour % 24) == 0 ) {
                day++;
                hour = 0;
            }
        } // end 60 minute check
    } // end 60 second check
} // end doTick()

No unnecessary checks or increments.

However, if you want accurate time use the JavaScript Date object (assuming you are using JavaScript). As another commenter said, in the real world you generally can't rely on something calling your function exactly every second.

5
  • Since you're already calculating the modulo, why would you do an extra check on it rather than just assigning the result to the value (or parseInt(value/60), where appropriate)? This seems like it's not only mostly unnecessary code, it is also likely to be inaccurate. Commented Nov 10, 2013 at 3:58
  • @AmyBlankenship I made some updates based on your comments, but did not "fix" the underlying issue. 59 times out of 60, this code will perform one increment and one modulo operation. This is quicker than using only a second variable and slicing it up into hour/minute/second every second using modulo and division. Commented Nov 10, 2013 at 4:14
  • 3
    Hmm, broken code like this is exactly what Mason Wheeler and I were trying to prevent by our answers…
    – amon
    Commented Nov 10, 2013 at 8:22
  • 1
    Javascript setTimer() and equivalents are garanteed to be executed at least after the timer. So your clock will slowly drift (and be completely out of sync if the JS process is suspended). The performance hit of running new Date() and updating the display is nothing on > 1990 hardware Commented Nov 10, 2013 at 10:50
  • 1
    @GlenPeterson Thank you for providing answer opposite to others. Though Mason Wheeler's and others' answers did changed my point of view (previously it was similar to yours), it is always a great added value to the discussion, if someone cares to show different opinion. Thanks, again!
    – trejder
    Commented Nov 12, 2013 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.