首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java编译器或JIT优化无参数静态方法

java编译器或JIT优化无参数静态方法
EN

Stack Overflow用户
提问于 2016-08-10 16:59:41
回答 1查看 225关注 0票数 0

我不精通java编译器,但我想知道java是否做了这样的优化。以下是问题所在:

代码语言:javascript
复制
class A {

private final static Map<String, String> fruitIds = new HashMap<String, String>();
static {

        fruitIds.put("Orange", "1");
        fruitIds.put("Apple", "2");
        fruitIds.put("banana", "4");    
}
    public static Set<Integer> getSortedFruitSet() {
        Iterator<String> iterator = fruitIds.values().iterator();
        Set<Integer> returnSet = new TreeSet<Integer>();
        while (iterator.hasNext()) {
            returnSet.add(Integer.valueOf(iterator.next()));
        }
        return returnSet;
    }
}

我知道我可以在这里使用枚举,但即使这样,我也可能会遇到同样的问题。每次我调用getSortedFruitSet时,它可能会创建新的TreeSet并填充它,这似乎是不必要的。我可以创建这个TreeSet的另一个静态实例,但是有没有其他方法来优化它呢?编译器或运行时是否对这种静态方法进行了优化?优化这样的方法调用有意义吗?

EN

回答 1

Stack Overflow用户

发布于 2016-08-10 17:09:03

java编译器不做这样的优化。

当我们用javap -c查看您的getSortedFruitSet()方法时,我们可以看到这段代码的编译版本。

代码语言:javascript
复制
    public static java.util.Set<java.lang.Integer> getSortedFruitSet();
descriptor: ()Ljava/util/Set;
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=2, locals=2, args_size=0
     0: getstatic     #2                  // Field fruitIds:Ljava/util/Map;
     3: invokeinterface #3,  1            // InterfaceMethod java/util/Map.values:()Ljava/util/Collection;
     8: invokeinterface #4,  1            // InterfaceMethod java/util/Collection.iterator:()Ljava/util/Iterator;
    13: astore_0
    14: new           #5                  // class java/util/TreeSet
    17: dup
    18: invokespecial #6                  // Method java/util/TreeSet."<init>":()V
    21: astore_1
    22: aload_0
    23: invokeinterface #7,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
    28: ifeq          53
    31: aload_1
    32: aload_0
    33: invokeinterface #8,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    38: checkcast     #9                  // class java/lang/String
    41: invokestatic  #10                 // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
    44: invokeinterface #11,  2           // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
    49: pop
    50: goto          22
    53: aload_1
    54: areturn
  LineNumberTable:
    line 13: 0
    line 14: 14
    line 15: 22
    line 16: 31
    line 18: 53
  StackMapTable: number_of_entries = 2
    frame_type = 253 /* append */
      offset_delta = 22
      locals = [ class java/util/Iterator, class java/util/Set ]
    frame_type = 30 /* same */
Signature: #36

因此,正如您所看到的,始终有一个newinvokespecial与TreeSet关联。(这将创建一个新的TreeSet对象,当您查看字节码时,创建过程分为两个步骤。一个步骤new和一个调用构造函数的invokespecial

JIT编译器(可能)可以做到这一点

JIT可以在这里进行优化,但它对频繁执行的方法进行优化。要测试这一点,您需要多次调用该方法,并查看JIT生成的汇编代码。我现在不能验证这一点,,但可能会返回到答案,所以稍后-如果在此期间没有其他人这样做的话。

很抱歉只回答了你问题的一部分。顺便说一句,Java编译器(从java到字节码)通常只做很少的优化:-)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38868669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档