在java中,单例比静态类快?
我需要对一段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
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();
}
}