1 /*
   2  * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.openjdk.bench.vm.lambda.capture;
  24 
  25 import org.openjdk.jmh.annotations.Benchmark;
  26 import org.openjdk.jmh.annotations.BenchmarkMode;
  27 import org.openjdk.jmh.annotations.Mode;
  28 import org.openjdk.jmh.annotations.OutputTimeUnit;
  29 import org.openjdk.jmh.annotations.Scope;
  30 import org.openjdk.jmh.annotations.State;
  31 
  32 import java.util.concurrent.TimeUnit;
  33 
  34 /**
  35  * evaluates anonymous classes creation (for comparison with lambda)
  36  *
  37  * Naming convention:
  38  *  - inner_N      - lambda captures N local variables
  39  *  - inner_this_N - lambda captures 'this' and N local variables
  40  *
  41  * @author Sergey Kuksenko (sergey.kuksenko@oracle.com)
  42  */
  43 @State(Scope.Benchmark)
  44 @BenchmarkMode(Mode.AverageTime)
  45 @OutputTimeUnit(TimeUnit.NANOSECONDS)
  46 public class Capture0 {
  47 
  48     /*
  49      *  volatile is used in order to avoid constant propagation
  50      *  That is why the bench is relevant only on TSO platforms (x86, SPARC).
  51      *  ARM & PPC - TBD when necessary.
  52      */
  53     public volatile int wh0 = 0;
  54     public volatile int wh1 = 1;
  55     public volatile int wh2 = 2;
  56     public volatile int wh3 = 3;
  57     public volatile int wh4 = 4;
  58     public volatile int wh5 = 5;
  59     public volatile int wh6 = 6;
  60     public volatile int wh7 = 7;
  61 
  62     public String fortyTwo = "42";
  63 
  64     @Benchmark()
  65     public FunctionalInterface0 inner0(){
  66         return new FunctionalInterface0() {
  67             @Override
  68             public Object foo() {
  69                 return "42";
  70             }
  71         };
  72     }
  73 
  74     @Benchmark()
  75     public FunctionalInterface0 inner_1(){
  76         final int l0 = wh0;
  77         return new FunctionalInterface0() {
  78             @Override
  79             public Object foo() {
  80                 return "42" + l0;
  81             }
  82         };
  83     }
  84 
  85 
  86     @Benchmark()
  87     public FunctionalInterface0 inner_2(){
  88         final int l0 = wh0;
  89         final int l1 = wh1;
  90         return new FunctionalInterface0() {
  91             @Override
  92             public Object foo() {
  93                 return "42" + l0 + " " + l1;
  94             }
  95         };
  96     }
  97 
  98     @Benchmark()
  99     public FunctionalInterface0 inner_4(){
 100         final int l0 = wh0;
 101         final int l1 = wh1;
 102         final int l2 = wh2;
 103         final int l3 = wh3;
 104         return new FunctionalInterface0() {
 105             @Override
 106             public Object foo() {
 107                 return "42" + l0 + " " + l1 + " " + l2 + " " + l3;
 108             }
 109         };
 110     }
 111 
 112 
 113     @Benchmark()
 114     public FunctionalInterface0 inner_8(){
 115         final int l0 = wh0;
 116         final int l1 = wh1;
 117         final int l2 = wh2;
 118         final int l3 = wh3;
 119         final int l4 = wh4;
 120         final int l5 = wh5;
 121         final int l6 = wh6;
 122         final int l7 = wh7;
 123         return new FunctionalInterface0() {
 124             @Override
 125             public Object foo() {
 126                 return "42" + l0 + " " + l1 + " " + l2 + " " + l3 +
 127                         " " + l4 + " " + l5 + " " + l6 + " " + l7;
 128             }
 129         };
 130     }
 131 
 132     @Benchmark()
 133     public FunctionalInterface0 inner_this_0(){
 134         return new FunctionalInterface0() {
 135             @Override
 136             public Object foo() {
 137                 return fortyTwo;
 138             }
 139         };
 140     }
 141 
 142     @Benchmark()
 143     public FunctionalInterface0 inner_this_1(){
 144         final int l0 = wh0;
 145         return new FunctionalInterface0() {
 146             @Override
 147             public Object foo() {
 148                 return fortyTwo + l0;
 149             }
 150         };
 151     }
 152 
 153 
 154     @Benchmark()
 155     public FunctionalInterface0 inner_this_2(){
 156         final int l0 = wh0;
 157         final int l1 = wh1;
 158         return new FunctionalInterface0() {
 159             @Override
 160             public Object foo() {
 161                 return fortyTwo + l0 + " " + l1;
 162             }
 163         };
 164     }
 165 
 166     @Benchmark()
 167     public FunctionalInterface0 inner_this_4(){
 168         final int l0 = wh0;
 169         final int l1 = wh1;
 170         final int l2 = wh2;
 171         final int l3 = wh3;
 172         return new FunctionalInterface0() {
 173             @Override
 174             public Object foo() {
 175                 return fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3;
 176             }
 177         };
 178     }
 179 
 180 
 181     @Benchmark()
 182     public FunctionalInterface0 inner_this_8(){
 183         final int l0 = wh0;
 184         final int l1 = wh1;
 185         final int l2 = wh2;
 186         final int l3 = wh3;
 187         final int l4 = wh4;
 188         final int l5 = wh5;
 189         final int l6 = wh6;
 190         final int l7 = wh7;
 191         return new FunctionalInterface0() {
 192             @Override
 193             public Object foo() {
 194                 return fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3 +
 195                         " " + l4 + " " + l5 + " " + l6 + " " + l7;
 196             }
 197         };
 198     }
 199 
 200 //--------------------lambda part
 201 
 202     @Benchmark()
 203     public FunctionalInterface0 lambda_00(){
 204         return () -> "42";
 205     }
 206 
 207     @Benchmark()
 208     public FunctionalInterface0 lambda_01(){
 209         int l0 = wh0;
 210         return () -> "42" + l0;
 211     }
 212 
 213 
 214     @Benchmark()
 215     public FunctionalInterface0 lambda_02(){
 216         int l0 = wh0;
 217         int l1 = wh1;
 218         return () -> "42" + l0 + " " + l1;
 219     }
 220 
 221     @Benchmark()
 222     public FunctionalInterface0 lambda_04(){
 223         int l0 = wh0;
 224         int l1 = wh1;
 225         int l2 = wh2;
 226         int l3 = wh3;
 227         return () -> "42" + l0 + " " + l1 + " " + l2 + " " + l3;
 228     }
 229 
 230 
 231     @Benchmark()
 232     public FunctionalInterface0 lambda_08(){
 233         int l0 = wh0;
 234         int l1 = wh1;
 235         int l2 = wh2;
 236         int l3 = wh3;
 237         int l4 = wh4;
 238         int l5 = wh5;
 239         int l6 = wh6;
 240         int l7 = wh7;
 241         return () -> "42" + l0 + " " + l1 + " " + l2 + " " + l3 + " " + l4 + " " + l5 + " " + l6 + " " + l7;
 242     }
 243 
 244     @Benchmark()
 245     public FunctionalInterface0 lambda_this_0(){
 246         return () -> fortyTwo;
 247     }
 248 
 249     @Benchmark()
 250     public FunctionalInterface0 lambda_this_1(){
 251         int l0 = wh0;
 252         return () -> fortyTwo + l0;
 253     }
 254 
 255 
 256     @Benchmark()
 257     public FunctionalInterface0 lambda_this_2(){
 258         int l0 = wh0;
 259         int l1 = wh1;
 260         return () -> fortyTwo + l0 + " " + l1;
 261     }
 262 
 263     @Benchmark()
 264     public FunctionalInterface0 lambda_this_4(){
 265         int l0 = wh0;
 266         int l1 = wh1;
 267         int l2 = wh2;
 268         int l3 = wh3;
 269         return () -> fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3;
 270     }
 271 
 272 
 273     @Benchmark()
 274     public FunctionalInterface0 lambda_this_8(){
 275         int l0 = wh0;
 276         int l1 = wh1;
 277         int l2 = wh2;
 278         int l3 = wh3;
 279         int l4 = wh4;
 280         int l5 = wh5;
 281         int l6 = wh6;
 282         int l7 = wh7;
 283         return () -> fortyTwo + l0 + " " + l1 + " " + l2 + " " + l3 +
 284                 " " + l4 + " " + l5 + " " + l6 + " " + l7;
 285     }
 286 
 287 
 288 
 289 }