/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.contept;

import net.ranides.assira.text.*;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Pattern;
import net.ranides.assira.collection.arrays.ArrayUtils;
import net.ranides.assira.math.MathUtils;
import net.ranides.benchmark.app.BenchmarkName;
import net.ranides.benchmark.app.BenchmarkRunner;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.RunnerException;

/**
 * 3 measurements:
 *      interface   2'704   104.2 %
 *      abstract    2'576    99.3 %
 *      concrete    2'594   100.0 %
 * 
 * 10 measurements:
 *      interface   2'582   104.9 %
 *      abstract    2'459    99.9 %
 *      concrete    2'461   100.0 %
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class InvocationBenchmark {
    
    private static ITestInterface mInterface = new CTestInterface();
    
    private static ITestAbstract mAbstract = new CTestAbstract();
    
    private static CTestConcrete mConcrete = new CTestConcrete();
       
    @Benchmark
    @BenchmarkName("interface")
    public int timeInterface() {
        return mInterface.apply();
    }
    
    @Benchmark
    @BenchmarkName("abstract")
    public int timeAbstract() {
        return mAbstract.apply();
    }
    
    @Benchmark
    @BenchmarkName("concrete")
    public int timeConcrete() {
        return mConcrete.apply();
    }
    

    public static void main(String[] args) throws IOException, RunnerException {
        BenchmarkRunner.run(InvocationBenchmark.class,10);
    }
    
    private static interface ITestInterface {
        int apply();
    }
    
    private static class CTestInterface implements ITestInterface {
        
        @Override
        public int apply() {
            return 777;
        }
    }
    
    private static abstract class ITestAbstract {
        public abstract int apply();
    }
    
    private static class CTestAbstract extends ITestAbstract {
        
        @Override
        public int apply() {
            return 777;
        }
    }
    
    private static class CTestConcrete {
        
        public int apply() {
            return 777;
        }
    }
}
