【问题标题】:Will the optimizer prevent the creation of a string parameter if a constant will prevent it from being used?如果常量会阻止使用它,优化器会阻止创建字符串参数吗?
【发布时间】:2013-03-29 20:40:41
【问题描述】:

我的问题最好举个例子。

  public static boolean DEBUG = false;

  public void debugLog(String tag, String message) {
    if (DEBUG)
      Log.d(tag, message);
  }

  public void randomMethod() {
    debugLog("tag string", "message string"); //Example A

    debugLog("tag string", Integer.toString(1));//Example B

    debugLog("tag string", generateString());//Example C 
  }


  public String generateString() {
    return "this string";
  }

我的问题是,在任何示例中,A、B 或 C - 因为字符串最终不会被使用,优化器会删除它吗?

或者换个方式问,是不是最好做如下,从而保证不会创建字符串对象?

  public void randomMethod() {
    if (DEBUG) debugLog("tag string", "message string"); //Example A

    if (DEBUG) debugLog("tag string", Integer.toString(1));//Example B

    if (DEBUG) debugLog("tag string", generateString());//Example C 
  }

【问题讨论】:

  • 优化器(如果写对了)应该删除它们。
  • 实际上,A 和 C 中的字符串是字面量,因此是 intern 的,因此无论哪种方式都不会创建字符串。但这对问题无关紧要,我明白你的意思。
  • @JesusRamos 编译器作者希望与您合作,关于正确性和实用性
  • @JesusRamos 在情况 C 中呢?撇开这个问题不谈,您是否可能依赖于被调用函数中发生的某些处理?
  • @delnan 好吧,如果分支变成 if (0),则字符串的实习将毫无意义(尽管仍然必须创建解析树,因此如果实习可能需要更多的工作来清理是否在解析期间完成)。当然,代码仍然必须被解析以确保正确性,并且就实用性而言,它可能取决于它。现在这并不意味着字符串应该包含在最终的二进制文件中(可能在一些中间编译单元中)。

标签: java android logging compiler-optimization


【解决方案1】:

似乎第一个sn-p没有删除它,但它是第二个:

public class TestCompiler {
    public static boolean DEBUG = false;
    private static void debug(Object o) {
        if (DEBUG) {
            System.out.println(o);
        }
    }
    public static void main(String[] args) {
        if (DEBUG) {
            System.out.println(new InnerClass());
        }
        System.out.println("now nested");
        debug(new InnerClass());
    }
    private static final class InnerClass {
        static {
            System.out.println("Innerclass initialized");
        }
    }
}

对我(openjdk7)来说,这会导致:

now nested
Innerclass initialized

意思是去掉了if (DEBUG) {...},但是方法调用没有,所以设置了方法参数。

【讨论】:

  • 它是指Android OS,但我认为在这种情况下结果是一样的。
  • 哦,我没有意识到这一点。 :O 但是,您也可以运行该测试,不是吗?
  • 是的,只是代替 main 函数,它将在 Activity 的 onCreate() 方法或其他方法中运行。
  • 我不了解这里的 cmets @androiddeveloper。反响还好吗?我会继续接受它。
  • 没关系。只是它是 Java 风格(带有 main 功能),而不是 Android 风格(带有活动等)。当然,你是提出这个问题的人,所以你必须决定它是否足够好。
猜你喜欢
  • 2010-09-11
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-11
  • 2016-12-27
  • 2019-03-13
相关资源
最近更新 更多