单身人士比java中的静态类更快?

时间:2016-01-03 08:29:12

标签: java static singleton

我需要大量优化一段java代码,以至于我想知道我是否应该在方法中使用局部变量,使用私有变量的单例或者使用所有静态变量的静态类。

注意:我从未读过这些变量,我在每次方法调用时重新初始化它们,因此不会从任何形式的内存中获取。

所以我根据自己的情况进行了一些测试,结果令我困惑:

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;
}

}

这给了我结果:

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

局部变量最快,这里并不奇怪。程序的本地部分也在某个阶段进行了优化(因为它没有真正做任何事情),所以它完全被跳过。令我感到困惑的是,单身人士比静态访问快10倍。

我的问题是:单身人士确实比静态课程更快,或者只是因为我的情况导致测试误导?

关于Singleton:我改为代码。添加了这个类:

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;
    }

}

这正是我嵌入到原始类中的原因,但只是为了澄清而做了。这是一个单身人士,不是吗?

然后我在主类中更改了这段代码:

    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));

我得到了相同的结果。

2 个答案:

答案 0 :(得分:0)

嗯,在正常情况下,static类将提供比Singleton模式更好的性能,因为static方法在编译时受限制。

此外,使用static类可避免(潜在)虚拟函数调用的开销,并且无需在使用时获取类的instance

它不应该使太多的差异,所以我不建议在任何情况下避免任何一个使用方便和清晰。

关于您的程序:您似乎甚至没有实现Singleton设计模式,您只是在类Test中创建了一个名为singleton的字段,并且每次都增加它。这不是单身人士(阅读this)。

答案 1 :(得分:0)

我的猜测是它与你正在运行的Java版本以及你的JIT如何优化loopunrolling(或者在这种情况下无法使用staticc)有更多关系。这里有关于循环展开的更多信息。 https://en.wikipedia.org/wiki/Loop_unrolling

因此,例如尝试摆脱一些开销。在这个例子中

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

将其更改为...

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

直接回答编译器出现问题的原因是一个完全不同的讨论,需要更好地查看JIT代码。

如果你的价值观与此相近,我会说这是“为什么”