0

Is there optimization provided for such variable declaration:

final int secondsInDay = 24 * 60 * 60;

This code on C++ won't even compile despite that additional_funct is not used at all:

#include <iostream>

void additional_funct(int num);


void main()
{
    std::cout << "just a text";
}


void additional_funct(int num)
{
    // For both lines will be shown "divide by zero"
    int var = 5 / 0;
    int another_var = num + (2 / 0);
}

This proves that C++ compiler does optimization for numeric literals expressions precalculating them before running. While same Java code will simply start to run:

package experimental_main;

public class Experimental_start {
    public static void main(String[] args) {
        // Will throw ArithmeticException "by zero"
        additionalMethod(2);
        System.out.println("just a text");
    }


    static void additionalMethod(int num) {
        int var = 5 / 0;
        int anotherVar = num + (2 / 0);
    }
}

I understand that javac does not compile code in C-language meaning. But maybe it provides optimization in some other way or its better to declare such numeric literals in this way:

// 24 * 60 * 60
final int secondsInDay = 86_400;
Cryptor
  • 347
  • 1
  • 3
  • 9
  • 2
    Take a look: `javap -c YourClass.class`. But a much more descriptive way to do this is to use `TimeUnit.DAYS.toSeconds(1)`. – Andy Turner May 17 '16 at 12:49
  • That C++ code *will* compile and run (if you change the signature of `main`), [but it gives warnings](http://ideone.com/DxgXMh). – Andy Turner May 17 '16 at 13:01
  • This code is given just for example. But about exactly `secondsInDay` declaration: shame to me =) I'm aware of `TimeUnit` but didn't even think about using it in this way. – Cryptor May 17 '16 at 13:46

3 Answers3

5

Although javac doesn't do any major optimisations, such an expression can be evaluated at javac level,

If you decompile the expression int secondsInDay = 24 * 60 * 60; you would get something like

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=1, locals=2, args_size=1
     0: ldc           #2                  // int 86400
     2: istore_1
     3: return
  LineNumberTable:
    line 7: 0
    line 9: 3

And #2 resides in the constant pool,

Constant pool:
 ...
#2 = Integer            86400

The expression was evaluated to its value 86400 as you can see.

Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77
4

Yes, javac will precompute compile-time constants. It will also concatenate compile-time constant strings, e.g. final String s = "foo" + "bar" would result in the string "foobar" in the string pool, not two strings "foo" and "bar".

You should always write your code for readability. If writing it as 24 * 60 * 60 makes more sense in terms of what you are writing, use that. Even if it weren't computed at compile time, I would treat any claim that this repeated multiplication were having a meaningful impact on your code's performance with great skepticism.

The cost of debugging the fact that you wrote 84_600 instead of 86_400 is orders of magnitude greater.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

The other answers are all correct (and in the end, a duplicate to this question) but there is one important aspect not mentioned so far.

Consider not doing it this way.

Of course it might be fully valid to use a primitive int to store a number of seconds. But: depending on your context, and how things are used ... it might be a much better design to actually use the power of OO modeling here. Meaning: if you want to express duration of time; then why not use objects and classes in order to represent those durations?

I have seen so many bugs where people were calling methods

someX.waitForGivenNumberOfSeconds()

like

someX.waitForGivenNumberOfSeconds(someValue * 1000)

Just because they did copy + paste; and overlooked that they copied from a place that was using milli seconds; and not seconds. Even with the method naming saying "give me seconds"; people passed "milli seconds". Or vice versa. And worse than that: far too often, the only visible indication might be some @param durationInSeconds attached to the source code of the method to call. So easy to get wrong. So easy to be changed later on, and rendering all existing code into chaos.

So, long story short: just step back for a second and decide if that "OO modeling" overhead might be appropriate for the "overall solution" you are working on.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248