Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中,单例比静态类快?_Java_Static_Singleton - Fatal编程技术网

在java中,单例比静态类快?

在java中,单例比静态类快?,java,static,singleton,Java,Static,Singleton,我需要对一段java代码进行大量优化,以至于我想知道是否应该在方法中使用局部变量,使用带有私有变量的单例,或者使用带有所有静态变量的“静态类” 注意:我从不读取这些变量,每次方法调用时我都会重新初始化它们,因此不会从任何形式的内存中提取 鉴于我的情况和结果,我做了一些测试: public class Test { private int singleton; private static int staticc; private static Test te; public static v

我需要对一段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;
}
局部变量是最快的,这一点也不奇怪。程序的局部部分也在某个阶段进行了优化(因为它实际上不做任何事情),所以它被完全跳过。让我困惑的是,单例访问比静态访问快10倍

我的问题是:是单例确实比静态类快,还是仅仅是我的情况让测试产生了误导

关于单例:我改为代码。添加了此类:

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));
long now=System.nanoTime();
对于(int i=0;i<1;i++){
对于(int j=0;j<100000000;j++){
Singleton.getInstance().single();
}
}
System.out.println(“singleton:”+(System.nanoTime()-now));

我得到了同样的结果。

在正常情况下,
静态
类将提供比
单例
模式更好的性能,因为
静态
方法在编译时是有限制的

另外,使用
静态
类可以避免虚拟函数调用的(潜在)开销,并且在使用该类时无需获取该类的
实例。

不过,这不会有太大的区别,所以我不建议在任何情况下避免使用这两种方法,因为使用起来既方便又清晰


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

我的猜测是,它与您正在运行的Java版本以及JIT如何优化循环展开(或者在本例中与staticc无关)有更多关系

例如,试着去掉一些开销

 now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 1000000000; j++){
            staticc();
        }
    }
now=System.nanoTime();
对于(int i=0;i<1;i++){
对于(int j=0;j<100000000;j++){
staticc();
}
}
把它改成

 now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 250000000; j++){
            staticc();
            staticc();
            staticc();
            staticc();
        }
    }
now=System.nanoTime();
对于(int i=0;i<1;i++){
对于(int j=0;j<250000000;j++){
staticc();
staticc();
staticc();
staticc();
}
}
给你一个编译器为什么会有问题的直接答案是一个完全不同的讨论,需要更好地了解JIT代码


如果您的值仅此一项就更接近,我会说这是“为什么”

这仍然无法回答为什么他的测试包含显著差异,但值得注意的是,我们将考虑这些信息。好吧,我创建了一个名为“te”的静态测试实例它保存字段singleton,然后调用该实例的非静态方法(也称为singleton)。我很确定这就是所谓的单例。静态实例???不,不。。。单例是一个类,我相信如果您正确定义了它,那么您的结果将与它们非常不同:)这不是单例模式。回顾这一点。你能尝试在你的方法之外给1一个初始值吗?然后让我知道时间?我可以这样做,但是CPU必须读取变量,这违反了测试的目的。对,我想看看测试的结果。我还没来得及称体重Psingleton:315151916静态:3092095119这些值不。。。但我相信这就是你所说的关于我的环境的话,而且很难解释我的测试。我真的想知道是否有一些我错过的常识,即单例确实比静态类快。但事实似乎并非如此。非常感谢。
 now = System.nanoTime();
    for (int i = 0; i < 1; i++){
        for (int j = 0; j < 250000000; j++){
            staticc();
            staticc();
            staticc();
            staticc();
        }
    }