Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.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_Performance - Fatal编程技术网

Java:不带变量的实例的性能

Java:不带变量的实例的性能,java,performance,Java,Performance,我上过这样的课: class Test { public static test getInstance() { return new test() } public void firstMethod() { //do something } public void secondMethod() { //do something } public void third

我上过这样的课:

class Test
{
    public static test getInstance()
    {
        return new test()
    }

    public void firstMethod()
    {
        //do something
    }
    public void secondMethod()
    {
        //do something
    }
    public void thirdMethod()
    {
        //do something
    }
}
在另一个类中,如果我们使用不同的方法多次调用
Test.getInstance().methodName()
,会发生什么? 在以下代码中,哪一个速度更快且内存较低

Test.getInstance().firstMethod()
Test.getInstance().secondMethod()
Test.getInstance().thirdMethod()

这将创建
Test
类的三个不同实例,并对每个实例调用一个方法

Test test = Test.getInstance();
test.firstMethod();
test.secondMethod();
test.thirdMethod();
将仅创建一个实例并在该实例上调用三个方法

所以这是一个完全不同的行为开始。显然,因为第一个创建了三个对象,所以它应该占用更多的堆空间

但是,如果您打算实现一个单例类,那么这两个类是等价的

这将创建
Test
类的三个不同实例,并对每个实例调用一个方法

Test test = Test.getInstance();
test.firstMethod();
test.secondMethod();
test.thirdMethod();
将仅创建一个实例并在该实例上调用三个方法

所以这是一个完全不同的行为开始。显然,因为第一个创建了三个对象,所以它应该占用更多的堆空间


但是,如果您打算实现一个单例类,那么这两个类是等效的。

每次调用
getInstance
时,系统都必须为
测试
对象分配堆存储并对其进行初始化


此外,在接下来的某个地方,系统将不得不对所有这些额外的
Test
对象进行垃圾收集。使用复制收集器,每个对象的开销是最小的,但也有一些开销——如果不是因为其他原因,而是因为您导致GC更频繁地发生。

每次调用
getInstance
时,系统都必须为
测试
对象分配堆存储并对其进行初始化

class Test 
{
    public static Test getInstance() 
    {
        return new Test();
    }

    public void firstMethod() 
    {
        // do something
    }

    public void secondMethod() 
    {
        // do something
    }

    public void thirdMethod() 
    {
        // do something
    }
}

public class Blah 
{
    public static void main(String[] args) 
    {
        int i = 0;
        long start = System.nanoTime();
        Test t = new Test();
        for (; i < 100000; i++) 
        {
            t.firstMethod();
        }
        long stop = System.nanoTime();
        System.out.println(stop - start);
        i = 0;
        start = System.nanoTime();
        for (; i < 100000; i++) 
        {
            Test.getInstance().firstMethod();
        }
        stop = System.nanoTime();
        System.out.println(stop - start);

    }
}
此外,在接下来的某个地方,系统将不得不对所有这些额外的
Test
对象进行垃圾收集。使用复制收集器,每个对象的开销是最小的,但也有一些——如果不是因为其他原因,就是因为您导致GC更频繁地发生的话

class Test 
{
    public static Test getInstance() 
    {
        return new Test();
    }

    public void firstMethod() 
    {
        // do something
    }

    public void secondMethod() 
    {
        // do something
    }

    public void thirdMethod() 
    {
        // do something
    }
}

public class Blah 
{
    public static void main(String[] args) 
    {
        int i = 0;
        long start = System.nanoTime();
        Test t = new Test();
        for (; i < 100000; i++) 
        {
            t.firstMethod();
        }
        long stop = System.nanoTime();
        System.out.println(stop - start);
        i = 0;
        start = System.nanoTime();
        for (; i < 100000; i++) 
        {
            Test.getInstance().firstMethod();
        }
        stop = System.nanoTime();
        System.out.println(stop - start);

    }
}
使用new Test()创建单个实例的速度持续提高了约30%

由于无法在一次运行中完成内存计算,因此内存计算更加困难。但是,如果我们只运行第一个循环(更改内部内容)并使用:

就在印刷之前。在两次单独的运行中,我们可以确定差异:
newtest()
~671200
~1342472
(似乎在运行之间随机变化,对运行时没有明显影响)和
getInstance()
~2389288
(这次没有大的差异)在100000次迭代中。再次明确胜利的单一实例

使用new Test()创建单个实例的速度持续提高了约30%

由于无法在一次运行中完成内存计算,因此内存计算更加困难。但是,如果我们只运行第一个循环(更改内部内容)并使用:


就在印刷之前。在两次单独的运行中,我们可以确定差异:
newtest()
~671200
~1342472
(似乎在运行之间随机变化,对运行时没有明显影响)和
getInstance()
~2389288
(这次没有大的差异)在100000次迭代中。再次明确的单实例胜利

@GáborBakos证明了itI不认为它会是任何的-它应该是相同的-原因是编译器优化了它。在一天结束时,所有东西都在Java的堆空间中,垃圾收集会丢弃你没有用完的东西。在第一个实例中唯一不同的是Test.getInstance().firstMethod()等的引用计数。只有一个
测试对象。我想肯定有人会把它放在他/她的答案中解释。我认为第二个更快,因为第一个会为每个方法调用创建一个新实例,对吗?除非它得到优化。当您使用
getInstance()
方法时,通常意味着您使用,这意味着只有第一个调用将创建一个
新测试
,并且所有后续调用都返回该实例。当您有一个应该在每次调用时返回新实例的时,请调用它
create()
makeTest()
。另外,当类的方法不使用任何变量时,您应该将它们设置为
静态
,并使用
Test.methodName
静态调用它们。请参阅下面的注释@Chris。所有对象都至少是
对象
的一个实例,它必须分配内存。这确实需要时间。@GáborBakos证明了这一点,我认为它不会有任何变化——它应该是相同的——原因是编译器无论如何都会对它进行优化。在一天结束时,所有东西都在Java的堆空间中,垃圾收集会丢弃你没有用完的东西。在第一个实例中唯一不同的是Test.getInstance().firstMethod()等的引用计数。只有一个
测试对象。我想肯定有人会把它放在他/她的答案中解释。我认为第二个更快,因为第一个会为每个方法调用创建一个新实例,对吗?除非它得到优化。当您使用
getInstance()
方法时,通常意味着您使用,这意味着只有第一个调用将创建一个
新测试
,并且所有后续调用都返回该实例。当您有一个应该在每次调用时返回新实例的时,请调用它
create()
makeTest()
。另外,当类的方法不使用任何变量时,您应该将它们设置为
静态
,并使用
Test.methodName
静态调用它们。请参阅下面的注释@Chris。所有对象都至少是
对象
的一个实例,它必须分配内存。这确实需要时间。而且由于每个对象都是
对象
,JIT可能无法完全优化对
new
的调用。因此,必须分配内存(以
~3486938
~4894574
Runtime runtime = Runtime.getRuntime();
long memory = runtime.totalMemory() - runtime.freeMemory();