package org.cache2k.benchmark;
/*
* #%L
* Benchmarks: implementation variants
* %%
* Copyright (C) 2013 - 2017 headissue GmbH, Munich
* %%
* 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.
* #L%
*/
import org.junit.After;
import org.cache2k.benchmark.util.AccessTrace;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Map;
import java.util.TreeMap;
/**
* @author Jens Wilke; created: 2013-12-08
*/
public class BenchmarkingBase {
static Map<String,String> benchmarkName2csv = new TreeMap<>();
static HashSet<String> onlyOneResult = new HashSet<>();
protected BenchmarkCacheFactory factory = new Cache2kFactory();
BenchmarkCache<Integer, Integer> cache = null;
public BenchmarkCache<Integer, Integer> freshCache(AccessTrace t, int _maxElements) {
return freshCache(_maxElements);
}
public BenchmarkCache<Integer, Integer> freshCache(int _maxElements) {
if (cache != null) {
throw new IllegalStateException("Two caches in one test? Please call destroyCache() first");
}
return cache = factory.create(_maxElements);
}
public void destroyCache() {
if (cache != null) {
cache.close();
cache = null;
}
}
@After
public void tearDown() {
destroyCache();
}
public final long runBenchmark(BenchmarkCache<Integer, Integer> c, AccessTrace t) {
Integer[] _trace = t.getObjectTrace();
if (c instanceof SimulatorPolicy) {
SimulatorPolicy p = (SimulatorPolicy) c;
for (Integer k : _trace) {
((SimulatorPolicy) c).record(k);
}
return p.getMissCount();
}
long _missCount = 0;
for (Integer k : _trace) {
Integer v = c.getIfPresent(k);
if (v == null) {
c.put(k, k);
_missCount++;
}
}
return _missCount;
}
public final int runBenchmark(AccessTrace t, int _cacheSize) {
BenchmarkCache<Integer, Integer> c;
c = freshCache(t, _cacheSize);
long _missCount = runBenchmark(c, t);
logHitRate(c, t, _missCount);
c.close();
return
((t.getTraceLength() - (int) _missCount) * 10000 + t.getTraceLength() / 2) / t.getTraceLength();
}
public void logHitRate(BenchmarkCache c, AccessTrace _trace, long _missCount) {
int _optHitRate = -1;
int _optHitCount = -1;
String _testName = extractTestName();
if (onlyOneResult.contains(_testName)) {
return;
}
onlyOneResult.add(_testName);
long _usedMem = -1;
saveHitRate(_testName, c.getCacheSize(), _trace, _optHitRate,_optHitCount, _missCount, _usedMem);
String _cacheStatistics = c.toString();
System.out.println(_cacheStatistics);
System.out.flush();
}
void saveHitRate(String _testName, int _cacheSize, AccessTrace _trace, int _optHitRate, int _optHitCount, long _missCount, long _usedMem) {
double _hitRateTimes100 =
(_trace.getTraceLength() - _missCount) * 100D / _trace.getTraceLength();
String _hitRate = String.format("%.2f", _hitRateTimes100);
String s = "";
if (_cacheSize > 0) {
s += "size=" + _cacheSize + ", ";
}
s += "accessCount=" + _trace.getTraceLength();
s += ", missCount=" + _missCount + ", hitRatePercent=" + _hitRate;
if (_optHitRate >= 0) {
s += ", optHitRatePercent=" + String.format("%.2f", _optHitRate * 1D / 100);
s += ", optHitCount=" + _optHitCount;
}
s += ", uniqueValues=" + _trace.getValueCount();
System.out.println(_testName + ": " + s);
int idx = _testName.lastIndexOf('.');
String _cacheImplementation = _testName.substring(0, idx);
String _benchmarkName = _testName.substring(idx + 1);
String _csvLine =
_benchmarkName + "|" + // 1
_cacheImplementation + "|" + // 2
String.format("%.2f", _hitRateTimes100) + "|" + // 3
_cacheSize + "|" + // 4
_trace.getTraceLength() + "|" + // 5
_trace.getValueCount(); // 6
if (!benchmarkName2csv.containsKey(_testName)) {
benchmarkName2csv.put(_testName, _csvLine);
writeCsv(_csvLine);
}
}
void writeCsv(String _csvLine) {
String s = System.getProperty("cache2k.benchmark.result.csv");
if (s == null) {
return;
}
try {
PrintWriter w = new PrintWriter(new FileWriter(s, true));
w.println(_csvLine);
w.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
String extractTestName() {
Exception e = new Exception();
int idx = 1;
StackTraceElement[] _stackTrace = e.getStackTrace();
do {
String n = _stackTrace[idx].getMethodName();
idx++;
if (n.startsWith("benchmark") || n.startsWith("test")) {
return this.getClass().getName() + "." + _stackTrace[idx - 1].getMethodName();
}
} while (true);
}
}