Previous in several ways to write a simple test, draw some preliminary conclusions. After this brief overview of Lambda principle, the test made some adjustments, find get a different result, and this adjustment, significantly more fit the actual development of the scene.
No personally to verify, mainly from the blog to understand the Lambda principle, cause some inspiration, the test codes have been some improvements.
Thank the author of this blog: https://www.cnblogs.com/UncleWang001/p/10020611.html - handling mechanisms underlying the lambda expression
Adjusted Code:
1 package com.supalle.test; 2 3 import lombok.AllArgsConstructor; 4 import lombok.Builder; 5 import lombok.Data; 6 import lombok.NoArgsConstructor; 7 8 import java.lang.reflect.Constructor; 9 import java.lang.reflect.InvocationTargetException; 10 import java.util.function.Supplier; 11 12 /** 13 * @描述:语法PK 14 * @作者:Supalle 15 * @时间:2019/7/26 16 */ 17 public class SyntaxPKTest { 18 is . 19 20 is / * cycles * / 21 is Private Final static int SIZE = 100000000 ; 22 is 23 is / * have the following classes * / 24 @Data 25 @Builder 26 is @NoArgsConstructor 27 @AllArgsConstructor 28 Private static class Man { 29 Private String name; 30 Private int Age; 31 is } 32 33 is 34 /** 35 * 使用 new Man(); 36 * 37 * @return 运行耗时 38 */ 39 public static long runWithNewConstructor() { 40 long start = System.currentTimeMillis(); 41 42 for (int i = 0; i < SIZE; i++) { 43 new SyntaxPKTest.Man(); 44 } 45 46 return System.currentTimeMillis() - start; 47 } 48 49 /** 50 * 使用反射 51 * 52 * @return 运行耗时 53 */ 54 public static long runWithReflex() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { 55 Constructor<SyntaxPKTest.Man> constructor = SyntaxPKTest.Man.class.getConstructor(); 56 long start = System.currentTimeMillis(); 57 58 for (int i = 0; i < SIZE; i++) { 59 Constructor.newInstance (); 60 } 61 is 62 is return System.currentTimeMillis () - Start; 63 is } 64 65 / ** 66 * Man inner class calls new new (); 67 * 68 * @return run Processed 69 * / 70 public static Long runWithSubClass () { 71 is Long Start = System.currentTimeMillis (); 72 73 is Supplier <Man> = new new Supplier Supplier <Man> () { 74 @Override 75 GET public Man () { Return new new Man 76 (); 77} 78}; 79 for ( int I = 0; I <SIZE; I ++ ) { 80 supplier.get (); 81 82 } 83 84 return System.currentTimeMillis () - Start; 85 } 86 87 / ** 88 * Man using a Lambda call new new (); 89 * 90 * @return run Processed 91 is * / 92 public static Long runWithLambda () { 93 long start = System.currentTimeMillis(); 94 95 Supplier<Man> supplier = () -> new Man(); 96 97 for (int i = 0; i < SIZE; i++) { 98 supplier.get(); 99 } 100 101 return System.currentTimeMillis() - start; 102 } 103 104 105 /** 106 * 使用 MethodReference 107 * 108 * @return 运行耗时 109 */ 110 public static long runWithMethodReference() { 111 long start = System.currentTimeMillis(); 112 113 Supplier<Man> supplier = Man::new; 114 115 for (int i = 0; i < SIZE; i++) { 116 supplier.get(); 117 } 118 119 return System.currentTimeMillis() - start; 120 } 121 122 public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { 123 124 // before the test call at loading bytecode Man, try to be fair 125 SyntaxPKTest.Man man1 = new new SyntaxPKTest.Man (); 126 SyntaxPKTest.Man man2 = new new SyntaxPKTest.Man ( "Joe Smith", 20 ); 127 128 System.out.println ( "test environment: CPU cores -" + . Runtime.getRuntime () availableProcessors ()); 129 130. System.out.println (); 131 is 132 // then called again here comparison time 133 System.out.println ( "first use new Man () takes:" + runWithNewConstructor ()); 134 System.err.println ( "again using new Man () takes:" + runWithNewConstructor ()); 135 System.out.println ( "first use reflective Processed:" + runWithReflex ()); 136 System.err.println ( "re-use reflection Processed:" + runWithReflex ()); 137 System.out.println ( " the first use of internal class to call the new Man () takes: "+ runWithSubClass ()); 138 System.err.println (" inner class used again to call new Man () takes: "+ runWithSubClass ()); 139 System.out .println ( "first use Lambda call new Man () takes:" + runWithLambda ()); 140 System.err.println ( "Lambda call again using new Man () takes:" + runWithLambda ()); 141 System .out.println ( "first use MethodReference time-consuming:" + runWithMethodReference ()); 142 System.err.println ( "reuse MethodReference Processed:" + runWithMethodReference ()); 143 144 145 } 146 147 }
This adjustment, just the inner class, Lambda, Method Reference into circulation outside, more in line with our common situation.
Test results are compared on a really big change.
1 for the first time new new Man () Processed: 4 2 Use new Man () again Processed: 1 . 3 for the first time reflected Processed: 237 4 Using again reflected Processed: 251 . 5 first inner class calls the new new Man () Processed : 5 . 6 again uses an internal class to call new Man () Processed: 2 . 7 first call using a Lambda new new Man () Processed: 41 . 8 again calls using a Lambda new Man () Processed: 3 . 9 first use MethodReference time: 4 10 again using MethodReference time: 1
1 for the first time new new Man () Processed: 3 2 Using the new Man () again Processed: 2 . 3 for the first time using a reflection Processed: 240 4 Using again reflected Processed: 256 . 5 first inner class calls the new new Man () Processed : 5 . 6 again uses an internal class to call new Man () Processed: 3 . 7 first call using a Lambda new new Man () Processed: 43 . 8 again calls using a Lambda new Man () time: 4 . 9 first time MethodReference time: 4 10 again using MethodReference time: 1
The first use of new new Man () time: 3 using the new Man again () time: 2 for the first time using reflection time: 238 again using reflection time: 251 for the first time using an internal class to call new new Man () time: 5 using internal again class calls the new Man () time: 1 for the first time using a Lambda call new new Man () time: 39 again using Lambda call new Man () time: 5 for the first time MethodReference time: 3 again using MethodReference time: 2
You can see Lambda Method Reference is also time-consuming and very small, mainly in its use creates a Supplier <Man> after instance implementing the interface, you create classes and objects inside out is not essentially different, so do not differ in performance Big.
in conclusion:
If it is necessary to maintain a flexible simple and pursuit of the ultimate performance, use when Lambda or Method Reference, try not to write in the inner loop.