/*
* Java Genetic Algorithm Library (@__identifier__@).
* Copyright (c) @__year__@ Franz Wilhelmstötter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author:
* Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
*/
package org.jenetics.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.jenetics.internal.util.IntRef;
/**
* @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
* @version 3.0
* @since 3.0
*/
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class SeqPerf {
static final int SIZE = 1000;
private final Random random = new Random();
private final int index = ThreadLocalRandom.current().nextInt(SIZE);
// The native integer array for performance testing
private final Integer[] array = new Integer[SIZE]; {
for (int i = 0; i < SIZE; ++i) {
array[i] = i;
}
}
// The ArrayList for performance testing
private final ArrayList<Integer> arrayList = new ArrayList<>(SIZE); {
for (int i = 0; i < SIZE; ++i) {
arrayList.add(i);
}
}
// The MSeq for performance testing
private final MSeq<Integer> mseq = MSeq.ofLength(SIZE); {
for (int i = 0; i < SIZE; ++i) {
mseq.set(i, i);
}
}
/* *************************************************************************
* Native array performance tests.
**************************************************************************/
@OperationsPerInvocation(SIZE)
@Benchmark
public int array_get() {
int sum = 0;
for (int i = 0; i < SIZE; ++i) {
sum += array[i];
}
return sum;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int array_set() {
final Integer value = random.nextInt();
for (int i = 0; i < SIZE; ++i) {
array[i] = value;
}
return value;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int array_forLoop() {
int sum = 0;
for (Integer i : array) {
sum += i;
}
return sum;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int array_copy() {
return array.clone()[0].hashCode();
}
/* *************************************************************************
* ArrayList performance tests.
**************************************************************************/
@OperationsPerInvocation(SIZE)
@Benchmark
public int arrayList_get() {
int sum = 0;
for (int i = 0; i < SIZE; ++i) {
sum += arrayList.get(i);
}
return sum;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int arrayList_set() {
final Integer value = random.nextInt();
for (int i = 0; i < SIZE; ++i) {
arrayList.set(i, value);
}
return value;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int arrayList_forLoop() {
int sum = 0;
for (Integer i : arrayList) {
sum += i;
}
return sum;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int arrayList_forEachLoop() {
final IntRef sum = new IntRef();
arrayList.forEach(i -> sum.value += i);
return sum.value;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int arrayList_contains() {
int count = 0;
for (int i = 0; i < SIZE; ++i) {
count += arrayList.contains(i) ? 1 : 0;
}
return count;
}
@OperationsPerInvocation(SIZE)
@Benchmark
@SuppressWarnings("unchecked")
public int arrayList_copy() {
return ((List<Integer>)arrayList.clone()).get(0);
}
/* *************************************************************************
* MSeq performance tests.
**************************************************************************/
@OperationsPerInvocation(SIZE)
@Benchmark
public int mseq_get() {
int sum = 0;
for (int i = 0; i < SIZE; ++i) {
sum += mseq.get(i);
}
return sum;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int mseq_set() {
final Integer value = random.nextInt();
for (int i = 0; i < SIZE; ++i) {
mseq.set(i, value);
}
return value;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int mseq_forLoop() {
int sum = 0;
for (Integer i : mseq) {
sum += i;
}
return sum;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int mseq_forEachLoop() {
final IntRef sum = new IntRef();
mseq.forEach(i -> sum.value += i);
return sum.value;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int mseq_contains() {
int count = 0;
for (int i = 0; i < SIZE; ++i) {
count += mseq.contains(i) ? 1 : 0;
}
return count;
}
@OperationsPerInvocation(SIZE)
@Benchmark
public int mseq_copy() {
return mseq.copy().get(0);
}
public static void main(String[] args) throws RunnerException {
final Options opt = new OptionsBuilder()
.include(".*" + SeqPerf.class.getSimpleName() + ".*")
.warmupIterations(3)
.measurementIterations(5)
.threads(1)
.forks(1)
.build();
new Runner(opt).run();
}
}