简体   繁体   English

Java编译器是否优化了流过滤?

[英]Does Java compiler optimize stream filtering?

Let's have a case: 我们有一个案例:

x.stream().filter(X::isFlag).filter(this::isOtherFlag).reduce(...)

Does it differ from this one? 它与这个不同吗?

x.stream().filter(predicate(X::isFlag).and(this::isOtherFlag)).reduce(...)

Functionally, the two statements are equivalent. 从功能上讲,这两个陈述是等价的。 However, consider the two following blocks of code and their respective bytecodes: 但是,请考虑以下两个代码块及其各自的字节码:

public static void main(String[] args) {
    List<String> list = List.of("Seven", "Eight", "Nine");

    list.stream().filter(s -> s.length() >= 5)
                 .filter(s -> s.contains("n"))
                 .forEach(System.out::println);
}

public static void main(java.lang.String[]);
Code:
   0: ldc           #16                 // String Seven
   2: ldc           #18                 // String Eight
   4: ldc           #20                 // String Nine
   6: invokestatic  #22                 // InterfaceMethod java/util/List.of:(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
   9: astore_1
  10: aload_1
  11: invokeinterface #28,  1           // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
  16: invokedynamic #35,  0             // InvokeDynamic #0:test:()Ljava/util/function/Predicate;
  21: invokeinterface #36,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
  26: invokedynamic #42,  0             // InvokeDynamic #1:test:()Ljava/util/function/Predicate;
  31: invokeinterface #36,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
  36: getstatic     #43                 // Field java/lang/System.out:Ljava/io/PrintStream;
  39: invokedynamic #52,  0             // InvokeDynamic #2:accept:(Ljava/io/PrintStream;)Ljava/util/function/Consumer;
  44: invokeinterface #53,  2           // InterfaceMethod java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V
  49: return

- -

public static void main(String[] args) {
    List<String> list = List.of("Seven", "Eight", "Nine");

    list.stream().filter(s -> s.length() >= 5 && s.contains("n"))
                 .forEach(System.out::println);
}

public static void main(java.lang.String[]);
Code:
   0: ldc           #16                 // String Seven
   2: ldc           #18                 // String Eight
   4: ldc           #20                 // String Nine
   6: invokestatic  #22                 // InterfaceMethod java/util/List.of:(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
   9: astore_1
  10: aload_1
  11: invokeinterface #28,  1           // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
  16: invokedynamic #35,  0             // InvokeDynamic #0:test:()Ljava/util/function/Predicate;
  21: invokeinterface #36,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
  26: getstatic     #42                 // Field java/lang/System.out:Ljava/io/PrintStream;
  29: invokedynamic #51,  0             // InvokeDynamic #1:accept:(Ljava/io/PrintStream;)Ljava/util/function/Consumer;
  34: invokeinterface #52,  2           // InterfaceMethod java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V
  39: return

We can see that, in the second example, one call to invokedynamic and invokeinterface are missing (which makes sense as we omitted a call to filter ). 我们可以看到,在第二个例子中,缺少对invokedynamicinvokeinterface一次调用(这是有意义的,因为我们省略了对filter的调用)。 I'm sure someone could assist with me with the static analysis of this bytecode (I can post verbose files if needed), but the Java compiler clearly treats the single call to filter as a single Predicate<String> rather than splitting it at the operator && , shortening the bytecode slightly. 我确信有人可以帮助我对这个字节码进行静态分析(如果需要,我可以发布详细文件),但Java编译器明确将单个调用filter为单个Predicate<String>而不是将其拆分为operator && ,略微缩短字节码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM