-1

I need to heavily optimize a piece of java code to the point that I'm wondering if I should use local variables in methods, singletons with private variables or "static classes with all static variables.

NOTE: I never read these variables, I initialize them anew on each method call, so there is no fetching from any form of memory.

So I Made some tests, given my situation and the result baffled me:

public class Test {

private int singleton;
private static int staticc;
private static Test te;

public static void main(String[] args) {

    te = new Test();
    for (int i = 0; i < 10; i++)
        t();
}

private static void t(){

    long now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            te.singleton();
        }
    }
    System.out.println("singleton: " + (System.nanoTime() - now));

    now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            staticc();
        }
    }
    System.out.println("static:    " + (System.nanoTime() - now));

    now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            local();
        }
    }
    System.out.println("local:     " + (System.nanoTime() - now));

    now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            overhead();
        }
    }
    System.out.println("overhead:  " + (System.nanoTime() - now));
}

private void singleton(){
    singleton = 1;
    singleton += singleton;

}

private static void staticc(){
    staticc = 1;
    staticc += staticc;
}

private static void local(){

    float local = 1;
    local += local;
}

private static void overhead(){
    return;
}

}

Which gave me the result:

singleton: 24460647
static:    41413757
local:     2630802
overhead:  2488400
singleton: 30776796
static:    19671150
local:     5132
overhead:  5131
singleton: 19669867
static:    144606898
local:     5559
overhead:  5560
singleton: 19399175
static:    143904724
local:     855
overhead:  428
singleton: 18892001
static:    143648143
local:     427
overhead:  428
singleton: 19543287
static:    145828647
local:     855
overhead:  428
singleton: 19356838
static:    145032821
local:     855
overhead:  1711
singleton: 19559965
static:    143845710
local:     427
overhead:  428
singleton: 19744275
static:    145983878
local:     428
overhead:  855
singleton: 19622399
static:    145635357
local:     428
overhead:  427

Local variables are fastest, no surprise here. The local part of the program is also optimized at some stage (since it doesn't really do anything), so that it is skipped entirely. What baffles me is that singleton is up to 10x faster than static access.

My question is: could it be that singletons are indeed faster that static classes, or is it just my circumstances that makes the test misleading?

Regarding Singleton: I changed to code. Added this class:

public class Singleton {

    private static final Singleton INSTANCE = new Singleton();

    private int sing = 0;

    public static Singleton getInstance(){
        return INSTANCE;
    }

    public void single(){
        sing = 1;
        sing += sing;
    }

}

Which is exactly what I had nested into the original class, but just did it for clarification. It is a singleton, is it not?

Then I changed this code in the main class:

    long now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            Singleton.getInstance().single();
        }
    }
    System.out.println("singleton: " + (System.nanoTime() - now));

I got the same results.

Jake
  • 843
  • 1
  • 7
  • 18

2 Answers2

0

Well, under normal circumstances a static class will provide better performance than Singleton pattern, because static methods are bounded on compile time.

Also, using a static class avoids (potential) overhead of virtual function calls, and eliminates the need to get an instance of the class when you use it.

It shouldn't make much of a difference though, so I wouldn't recommend avoiding either one in any case that it is convenient and clearer to use.

Regarding your program: it seems that you didn't even implement a Singleton design pattern, you just created a field in the class Test called singleton and increased it each time. This is not a Singleton (read this).

Community
  • 1
  • 1
Idos
  • 15,053
  • 14
  • 60
  • 75
  • That still doesn't answer why his tests contain a significant difference – christopher clark Jan 03 '16 at 08:42
  • But it's appreciated information that will be taken into account. – Jake Jan 03 '16 at 08:44
  • Well, I create an static instance of Test called "te" that holds the field singleton and then call this instance's non-static method also called singleton. I'm pretty sure this is what's considered to be a singleton. – Jake Jan 03 '16 at 08:51
  • Static instance??? no no... A singleton is a class and i'm sure if you defined it correctly then your results will be very different from what they are :) – Idos Jan 03 '16 at 08:53
  • This is not a singleton pattern. review this. http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java – christopher clark Jan 03 '16 at 08:53
  • @Jake You changed the code which makes this a completely different question. What do you mean by "same results" ? Also, it doesn't seem that you are using the singleton instance correctly - you are still incrementing a *field* inside a Singleton *Class*. Please open a new question and ask that specifically. – Idos Jan 03 '16 at 09:15
  • I just don't think he gave us it all first. I'm okay with this question. – christopher clark Jan 03 '16 at 09:19
  • I refactored the code so that the use of the singleton pattern would become more apparent. I didn't change a bit of functionality, it was all for you. The singleton I use is an exact copy of what's on Wikipedia: [link](https://en.wikipedia.org/wiki/Singleton_pattern) along with hundreds of other sources explaining the concept of singletons. – Jake Jan 03 '16 at 09:20
  • The question is fine. A singleton would return an instance which them you'd presumably perform some operations on. The problem with the comparison originally was (perhaps) an implicit singleton pattern. – ChiefTwoPencils Jan 03 '16 at 09:21
0

My guess is it has more to do with the Java version you are running and how your JIT is optimizing loopunrolling(or in this case failing to do with staticc). Here is a bit more on loop unrolling. https://en.wikipedia.org/wiki/Loop_unrolling

So for example try getting rid of some of the overhead. In this example

 now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            staticc();
        }
    }

Change it to...

 now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 250000000; j++){
            staticc();
            staticc();
            staticc();
            staticc();
        }
    }

Giving you a direct answer as to why the compiler is having problems is a whole different discussion that would require a better look at the JIT code.

If your values get closer with this alone, I would say this is "Why"

christopher clark
  • 2,026
  • 5
  • 28
  • 47
  • The values don't... But I'm sure it's what you're saying regarding my environment and it's neigh impossible to explain my test. I really wanted to know if there was some common knowledge that I'd missed, that singletons were indeed faster than static classes. But it seems that this isn't the case. Thank you. – Jake Jan 03 '16 at 09:27