【问题标题】:Excess instantination of the same object?同一对象的过度实例化?
【发布时间】:2013-01-23 09:02:09
【问题描述】:

将以下代码视为该想法的完全简化示例:

public class Main {
    public static void foreach(int[] x, intVoid action) {
        for (int i = 0; i < x.length; ++i) {
            action.apply(x[i]);
        }
    }

    public static void main (String[] args) {
        int[] h = new int[] {2, 3, 5, 7, 11, 13};
        for (int i = 0; i < 10; ++i) {
            foreach(h, new intVoid() {
                public void apply(int x) {
                    System.out.println(x * 2);
                }
            });
        }
    }
}

interface intVoid {public void apply(int x);}

在for循环中,我们调用foreach,从逻辑的角度来看具有完全相同的参数,因为我们接口的匿名实现不依赖于上下文中的任何内容。问题是——它会被实例化 10 次还是只被实例化一次?或者,类似的,它是否等同于以下代码:

public class Main {
    public static void foreach(int[] x, intVoid action) {
        for (int i = 0; i < x.length; ++i) {
            action.apply(x[i]);
        }
    }

    public static void main (String[] args) {
        int[] h = new int[] {2, 3, 5, 7, 11, 13};
        intVoid action = new intVoid() {
            public void apply(int x) {
                System.out.println(x * 2);
            }
        };
        for (int i = 0; i < 10; ++i) {
            foreach(h, action);
        }
    }
}

interface intVoid {public void apply(int x);}

我有时会遇到这种情况,在需要的地方准确定义实现非常方便,但有时我还需要确保不会尝试多次创建同一个对象。 如果运行时有优化,那么我对如何在不同的实现中进行处理很感兴趣,特别是如果我将此类代码转换为在 Android 的 Dalvik VM 中运行会发生什么。
我知道我可以自己测试这一切,但我想知道是否有人已经对这个问题有所了解。

【问题讨论】:

    标签: java optimization jvm java-7 dalvik


    【解决方案1】:

    问题是 - 它会被实例化 10 次还是只实例化一次?

    10 次,因为这是你告诉它要做的。看到 JVM(或 Dalvik)注意到 apply 没有副作用并且对象没有状态,我会感到惊讶,因此您不需要创建单独的实例。这是可能 - Hotspot 相当令人印象深刻 - 但对我来说这似乎不太可能优化。

    当然,创建每个对象可能很便宜 - 但按照您的第二个代码 sn-p 创建 一个 对象仍然会更好。

    【讨论】:

    • 所以我只有两个选择:像第二个示例那样编写代码,或者花一年时间创建另一种不太酷的 JVM 编译语言,对吧?
    • @SargeBorsch:或者忍受轻微的性能损失。您经常需要在优化代码和清晰代码之间找到平衡点。确保在需要的地方进行优化,并以能够产生显着差异的方式进行优化。
    【解决方案2】:

    每执行一次new,就会实例化一次。逃逸分析可能会在它被 JITed 之后消除它,例如10,000 次之后,但我不认为它确实如此。

    如果它足够聪明,不会创建单独的实例,那么它足够聪明,可以消除它,这样会更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 2010-09-15
      相关资源
      最近更新 更多