in reply to (tye)Re: Converting Seconds to Nice Format
in thread Converting Seconds to Nice Format

You, too, are computing 60*60*24*365 -- you are simply hiding the computation in the routine. One could argue that, for an implementation like this, simply doing the multiplication once and coding the integers directly is a cleaner, faster route. Or not :)

Anyway, in my continuing crusade as champion for the lovely % I would like to point out that

$left= int( $left / $_ ); $unit -= $left * $_;
could be "better" written as
$left= int( $left / $_ ); $unit %= $_;
Toss in a
use integer;
(in the subroutine BLOCK) and you can drop the call to int() as well - but be careful with this since this makes calls to % platform dependent (usually only an issue with negative numbers, not a problem here).

Replies are listed 'Best First'.
(tye)Re2: Converting Seconds to Nice Format
by tye (Sage) on Nov 13, 2000 at 22:11 UTC

    You, too, are computing 60*60*24*365

    Yes, but the point was that most of the other samples compute it directly and so they end up computing 60*60 three times and 60*60*24 twice as well as repeating the "number of seconds per minute" 4 times, "minutes per hour" 3 times, etc. I guess the added computations are done at compile time so they matter very little. But if anything I think not computing it directly is likely to be slightly faster and a little cleaner.

    Not that any of that is a big deal. I just saw the question, thought of how I've done that many times, figured several people were probably already composing answers, and decided I'd spend my time on something else. Later I wandered back and found quite a few answers, none of which did it the way I usually do. I didn't think my way was so strange so I decided to post it as an example of a different approach and I mentioned the key difference. I wasn't trying to claim that all of the other answers were inferior, in case you got that impression.

    $left= int( $left / $_ ); $unit %= $_;

    FYI, I'm don't think that saves you any computations since % just does a divide and takes a remainder. So you have done two divides where my method only does one divide and one multiply. I actually consciously chose my method over using % to avoid the duplicate divide, but that was probably a mistake on my part. I should have just gone with the cleaner code as you suggest. Thanks.

    I don't recall how floating-point remainders are computed at the machine level. It seems that integer remainders under C had the property that if you did an integer divide next to computing the corresponding remainder (modulus), then most platforms optimized that to a single instruction. But I doubt that would apply to a Perl script even if you'd done use integer. But worrying about these kinds of details is rarely worth it (other than for the fun of it).

    Toss in a use integer;

    ...and the code wouldn't work on nearly as many input values. I'm probably use integer's single biggest detractor. Without use integer you get (about) 58-bit integers in Perl. With use integer you get 32-bit integers. I guess you could argue that noone needs to nicely format the number of seconds in over 136 years, but I don't want to restrict my routine just for sake of saving 5 characters [ especially not by adding 12 characters :) ].

            - tye (but my friends call me "Tye")
      Whoops! Didn't mean to sound confrontational. Mostly I was looking through and saw a place I thought
      %
      would be better used -- and I will admit I'm fuzzy on the actual under-the-hood implementation of this in Perl. I had it pegged as at least as fast as the multiplication and subtraction but it might be slower -- I just don't know. It fits my eye, end of story.

      Regarding the 60*60*24*365 issue, I still think it's best to just explicitly code 60, 3600, etc (and perhaps include the product notation as a comment).

      I will add that your example is creative and exploits the power of Perl, but at the same time some of the others are more transparent to casual perusers of the code. For enthusiasts I like yours, but if you're sharing with other maintainers a more "obvious" might be appropriate.

        I was torn on whether to just /msg this but decided there is a small chance that others might be interested.

        Whoops! Didn't mean to sound confrontational.

        Yeah. Ditto. For the record, I couldn't decide if you were feeling confrontational or not, but it crossed my mind.

        Yes, if I was writing this anywhere else, I probably would have used zero maps instead of two and one ?: instead of four. But I definitely would still not have repeated the seconds/minute (etc.) constants more than once. (:

                - tye (but my friends call me "Tye")