当前位置: 首页 > 知识库问答 >
问题:

java不可变类慢得多

程彭祖
2023-03-14

所以我创建了速度可变与不变的简单测试:

final class MutableInt {
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public MutableInt() {
        this(0);
    }

    public MutableInt(int value) {
        this.value = value;
    }   
}

final class ImmutableInt {
    private final int value;

    public ImmutableInt(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

public class TestImmutableSpeed {

    static long testMutable(final int arrLen) {
        MutableInt[] arrMutable = new MutableInt[arrLen];
        for (int i = 0; i < arrMutable.length; ++i) {
            arrMutable[i] = new MutableInt(i);
            for (int j = 0; j < arrMutable.length; ++j) {
                arrMutable[i].setValue(arrMutable[i].getValue() + j);
            }
        }
        long sumMutable = 0;
        for (MutableInt item : arrMutable) {
            sumMutable += item.getValue();
        }
        return sumMutable;
    }

    static long testImmutable(final int arrLen) {
        ImmutableInt[] arrImmutable = new ImmutableInt[arrLen];
        for (int i = 0; i < arrImmutable.length; ++i) {
            arrImmutable[i] = new ImmutableInt(i);
            for (int j = 0; j < arrImmutable.length; ++j) {
                arrImmutable[i] = new ImmutableInt(arrImmutable[i].getValue() + j);
            }
        }
        long sumImmutable = 0;
        for (ImmutableInt item : arrImmutable) {
            sumImmutable += item.getValue();
        }
        return sumImmutable;
    }

    public static void main(String[] args) {
        final int arrLen = 1<<14;

        long tmStart = System.nanoTime();
        System.out.println("sum = " + testMutable(arrLen));
        long tmMid = System.nanoTime();
        System.out.println("sum = " + testImmutable(arrLen));
        long tmEnd = System.nanoTime();

        System.out.println("speed comparison mutable vs immutable:");
        System.out.println("mutable   " + (tmMid - tmStart)/1000000 + " ms");
        System.out.println("immutable " + (tmEnd - tmMid)/1000000 + " ms");
    }
}

如果测试运行得太慢/太快,您可以调整数组得大小.

我使用:-server-xms256m-xx:+actursiveopts运行,得到:

sum = 2199023247360
sum = 2199023247360
speed comparison mutable vs immutable:
mutable   102 ms
immutable 1506 ms
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;



final class MutableInt {
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public MutableInt() {
        this(0);
    }

    public MutableInt(int value) {
        this.value = value;
    }   
}

final class ImmutableInt {
    private final int value;

    public ImmutableInt(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}


public class TestImmutableSpeed extends SimpleBenchmark {

    static long testMutable(final int arrLen) {
        MutableInt[] arrMutable = new MutableInt[arrLen];
        for (int i = 0; i 
 0% Scenario{vm=java, trial=0, benchmark=Mutable, type=-server, minMemory=-Xms256m, optimizations=-XX:+AggressiveOpts} 91614044.60 ns; ?=250338.20 ns @ 3 trials
50% Scenario{vm=java, trial=0, benchmark=Immutable, type=-server, minMemory=-Xms256m, optimizations=-XX:+AggressiveOpts} 1108057922.00 ns; ?=3920760.98 ns @ 3 trials

benchmark     ms linear runtime
  Mutable   91.6 ==
Immutable 1108.1 ==============================
 0% Scenario{vm=java, trial=0, benchmark=Mutable} 516562214.00 ns; ?=623120.57 ns @ 3 trials
50% Scenario{vm=java, trial=0, benchmark=Immutable} 1706758503.00 ns; ?=5842389.60 ns @ 3 trials

benchmark   ms linear runtime
  Mutable  517 =========
Immutable 1707 ==============================

共有1个答案

甄志
2023-03-14

不变的值使Java中的编程更加干净。您不必到处复制,以避免在一段距离上出现可怕的操作(我的意思是在一个地方更改一个值,就会在无意中更改另一个地方的值)。删除副本会在某些地方加快速度,但创建新实例会在其他地方减慢速度。

(C++的有趣之处在于它采取了相反的方法。你可以在定义良好的点上获得副本,而不需要编写任何代码。实际上,你必须编写代码来删除副本。)

如果您关心的是性能,那么可变复合体也是不好的。有一个复杂的数组类,它使用隐藏在实现中的单个双数组,或者只使用RAW的双数组,会好得多。

 类似资料:
  • 问题内容: 我找到了一篇有趣的代码文章: 我真的很好奇了解创建此类的优势。我知道这里的此类对象是不可变的,因为一旦初始化就无法更改其变量值。我以前从未做过这样的事情,而且我真的不了解它的优势。 为什么是个好习惯? 您能说出可以使用这种方法的情况吗? 常量或只读变量呢?那不是很相似吗? 在文章中说,这不利于应用程序的性能。 但是为什么 呢? 问题答案: 您提到的示例是不可变对象。它在编程语言中被广泛

  • 问题内容: 通过遵循所有Java标准,我的班级变得一成不变 这些是我在定义不可变类时所做的主要检查点。 但是还有一个问题,我的对象仍然可以通过java反射进行修改,对吗?还是我在课堂上错过了任何一点? 提前致谢。 问题答案: 没有什么可以躲藏的-即使是不可变的类也不能幸免。但是,您对此无能为力,因此“无法通过反射进行修改”不是不变性的标准之一。

  • 问题内容: 为了使一类不变,我可以做的是: 1)将类设为final 2)不提供设置器 3)将所有变量标记为final 但是,如果我的班级有另一个班级的另一个对象,那么somone可以更改该对象的值 问题答案: A)也使不可变 要么 B)不允许直接访问对象,而是仅提供获取器以充当代理。 编辑添加: 您 可以 制作一个深层副本并返回一个副本,而不是原始副本,但这通常不是您在Java中期望的行为类型。

  • 问题内容: 我对什么是不可变类型感到困惑。我知道该float对象被认为是不可变的,在我的书中有这样的例子: 由于类的结构/层次结构,这是否被认为是不可变的?意思float是在类的顶部,是它自己的方法调用。类似于此类示例(即使我的书说的dict是可变的): 可变的东西在类内部具有方法,例如以下类型: 另外,对于最后一个,如果我将这种类型的set传递给它: 不调用该example方法,它返回一个字典。

  • 本文向大家介绍Python的可变类型和不可变类型?相关面试题,主要包含被问及Python的可变类型和不可变类型?时的应答技巧和注意事项,需要的朋友参考一下 可变数据类型:列表、字典、可变集合 不可变数据类型:数字、字符串、元组、不可变集合    

  • 本文向大家介绍JAVA不可变类(immutable)机制与String的不可变性(推荐),包括了JAVA不可变类(immutable)机制与String的不可变性(推荐)的使用技巧和注意事项,需要的朋友参考一下 一、不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String等。 可变类:相对