/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* UJMP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.complete.benchmark;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import org.ujmp.core.Matrix;
import org.ujmp.core.doublematrix.impl.DenseFileMatrix;
import org.ujmp.core.interfaces.Erasable;
import org.ujmp.core.objectmatrix.impl.SerializedSparseObjectMatrix;
import org.ujmp.core.util.MathUtil;
import org.ujmp.ehcache.EhcacheSparseObjectMatrix;
import org.ujmp.jdbc.matrix.JDBCSparseObjectMatrix;
import org.ujmp.lucene.LuceneSparseObjectMatrix;
public class VeryLargeMatrixBenchmark {
public static final int MATRIXSIZE = 10000;
public static final int MAXTIME = 30; // s
public static final int BURNINTIME = 10; // s
public static final int MAXENTRYCOUNT = 100000;
public static void main(String args[]) throws Exception {
System.out.println("Disk Matrix Benchmark");
System.out.println("=====================");
System.out.println("This benchmark creates a very large matrix on disk");
System.out.println("and measures the time for reading and writing data");
System.out.println();
System.out.println("Matrix size: " + MATRIXSIZE + "x" + MATRIXSIZE);
System.out.println("Main Memory: " + (Runtime.getRuntime().maxMemory() / 1000000) + "M");
System.out.println();
List<Matrix> matricesToTest = new LinkedList<Matrix>();
matricesToTest.add(new DenseFileMatrix(MATRIXSIZE, MATRIXSIZE));
matricesToTest.add(new SerializedSparseObjectMatrix(MATRIXSIZE, MATRIXSIZE));
matricesToTest.add(new LuceneSparseObjectMatrix(MATRIXSIZE, MATRIXSIZE));
matricesToTest.add(new JDBCSparseObjectMatrix(MATRIXSIZE, MATRIXSIZE));
matricesToTest.add(new EhcacheSparseObjectMatrix(MATRIXSIZE, MATRIXSIZE));
for (Matrix m : matricesToTest) {
System.out.println(m.getClass().getSimpleName());
// run the performance test
runPerformanceTest(m);
// clean up afterwards
if (m instanceof Erasable) {
((Erasable) m).erase();
}
}
}
private static void runPerformanceTest(Matrix m) throws Exception {
long t = System.currentTimeMillis();
long seed = t;
// burn in
Random random = new Random();
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
double value = MathUtil.nextDouble();
m.setAsObject(value, random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// write random entries to matrix
t = System.currentTimeMillis();
random = new Random(seed);
int writtenEntryCount = 0;
while (System.currentTimeMillis() - t < MAXTIME * 1000 && writtenEntryCount < MAXENTRYCOUNT) {
double value = MathUtil.nextDouble();
m.setAsObject(value, random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
writtenEntryCount++;
}
System.out.println(" Writing random entries");
printStatistics(System.currentTimeMillis() - t, writtenEntryCount, -1);
// burn in
t = System.currentTimeMillis();
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
m.getAsDouble(random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// read random entries from matrix
random = new Random();
t = System.currentTimeMillis();
int readEntryCount = 0;
int hitCount = 0;
while (System.currentTimeMillis() - t < MAXTIME * 1000) {
int row = random.nextInt(MATRIXSIZE);
int col = random.nextInt(MATRIXSIZE);
double v = m.getAsDouble(row, col);
readEntryCount++;
if (v != 0.0) {
hitCount++;
}
}
System.out.println(" Reading random entries");
printStatistics(System.currentTimeMillis() - t, readEntryCount, hitCount);
// burn in
t = System.currentTimeMillis();
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
m.getAsDouble(random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// read/write random entries in matrix
random = new Random();
t = System.currentTimeMillis();
readEntryCount = 0;
hitCount = 0;
while (System.currentTimeMillis() - t < MAXTIME * 1000 && readEntryCount < MAXENTRYCOUNT) {
int row = random.nextInt(MATRIXSIZE);
int col = random.nextInt(MATRIXSIZE);
double v = m.getAsDouble(row, col);
m.setAsDouble(v + 1, row, col);
readEntryCount++;
if (v != 0.0) {
hitCount++;
}
}
System.out.println(" Reading/writing random entries");
printStatistics(System.currentTimeMillis() - t, readEntryCount, hitCount);
// read non-zero entries from matrix
t = System.currentTimeMillis();
random = new Random(seed);
readEntryCount = 0;
hitCount = 0;
while (System.currentTimeMillis() - t < MAXTIME * 1000
&& readEntryCount < writtenEntryCount) {
int row = random.nextInt(MATRIXSIZE);
int col = random.nextInt(MATRIXSIZE);
double v = m.getAsDouble(row, col);
readEntryCount++;
if (v != 0.0) {
hitCount++;
}
}
System.out.println(" Reading random non-zero entries");
printStatistics(System.currentTimeMillis() - t, readEntryCount, hitCount);
// burn in
t = System.currentTimeMillis();
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
m.getAsDouble(random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// read/write non-zero entries from matrix
t = System.currentTimeMillis();
random = new Random(seed);
readEntryCount = 0;
hitCount = 0;
while (System.currentTimeMillis() - t < MAXTIME * 1000
&& readEntryCount < writtenEntryCount) {
int row = random.nextInt(MATRIXSIZE);
int col = random.nextInt(MATRIXSIZE);
double v = m.getAsDouble(row, col);
m.setAsDouble(v + 1, row, col);
readEntryCount++;
if (v != 0.0) {
hitCount++;
}
}
System.out.println(" Reading/writing random non-zero entries");
printStatistics(System.currentTimeMillis() - t, readEntryCount, hitCount);
// lucene takes a long time to recover after sequential write
if (m instanceof LuceneSparseObjectMatrix) {
System.out.println();
return;
}
// burn in
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
double value = MathUtil.nextDouble();
m.setAsObject(value, random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// write consecutive entries to matrix
t = System.currentTimeMillis();
writtenEntryCount = 0;
for (long r = 0; r < m.getRowCount(); r++) {
for (long c = 0; r < m.getColumnCount(); c++) {
double value = MathUtil.nextDouble();
m.setAsObject(value, r, c);
writtenEntryCount++;
if (System.currentTimeMillis() - t > MAXTIME * 1000
|| writtenEntryCount > MAXENTRYCOUNT) {
break;
}
}
}
System.out.println(" Writing consecutive entries");
printStatistics(System.currentTimeMillis() - t, writtenEntryCount, -1);
// burn in
t = System.currentTimeMillis();
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
m.getAsDouble(random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// read consecutive entries from matrix
t = System.currentTimeMillis();
readEntryCount = 0;
hitCount = 0;
for (long r = 0; r < m.getRowCount(); r++) {
for (long c = 0; r < m.getColumnCount(); c++) {
double v = m.getAsDouble(r, c);
readEntryCount++;
if (v != 0.0) {
hitCount++;
}
if (System.currentTimeMillis() - t > MAXTIME * 1000
|| readEntryCount > writtenEntryCount) {
break;
}
}
}
System.out.println(" Reading consecutive entries");
printStatistics(System.currentTimeMillis() - t, readEntryCount, hitCount);
// burn in
t = System.currentTimeMillis();
while (System.currentTimeMillis() - t < BURNINTIME * 1000) {
m.getAsDouble(random.nextInt(MATRIXSIZE), random.nextInt(MATRIXSIZE));
}
// read/write consecutive entries from matrix
t = System.currentTimeMillis();
readEntryCount = 0;
hitCount = 0;
for (long r = 0; r < m.getRowCount(); r++) {
for (long c = 0; r < m.getColumnCount(); c++) {
double v = m.getAsDouble(r, c);
m.setAsDouble(v + 1, r, c);
readEntryCount++;
if (v != 0.0) {
hitCount++;
}
if (System.currentTimeMillis() - t > MAXTIME * 1000
|| readEntryCount > writtenEntryCount) {
break;
}
}
}
System.out.println(" Reading/writing consecutive entries");
printStatistics(System.currentTimeMillis() - t, readEntryCount, hitCount);
System.out.println();
}
private static void printStatistics(long time, int count, int hits) {
double speed = (double) count / time * 1000.0;
double throughput = (double) speed * 8.0 / 1000.0;
System.out.println(" time: " + time / 1000 + "s");
if (hits >= 0) {
System.out.println(" count: " + hits + " hits of " + count);
} else {
System.out.println(" count: " + count);
}
System.out.println(" speed: " + speed + " entries/s");
System.out.println(" throughput: " + throughput + " KB/s");
}
}