/*
D-Bus Java Implementation
Copyright (c) 2005-2006 Matthew Johnson
This program is free software; you can redistribute it and/or modify it
under the terms of either the GNU Lesser General Public License Version 2 or the
Academic Free Licence Version 2.1.
Full licence texts are included in the COPYING file with this program.
*/
package org.freedesktop.dbus.test;
import java.util.Random;
import java.util.HashMap;
import java.util.Vector;
import org.freedesktop.DBus.Peer;
import org.freedesktop.DBus.Introspectable;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.DBusSigHandler;
import org.freedesktop.dbus.UInt32;
class ProfileHandler implements DBusSigHandler<Profiler.ProfileSignal>
{
public int c = 0;
public void handle(Profiler.ProfileSignal s)
{
if (0 == (c++%profile.SIGNAL_INNER)) System.out.print("-");
}
}
/**
* Profiling tests.
*/
public class profile
{
public static final int SIGNAL_INNER = 100;
public static final int SIGNAL_OUTER = 100;
public static final int PING_INNER = 100;
public static final int PING_OUTER = 100;
public static final int BYTES = 2000000;
public static final int INTROSPECTION_OUTER = 100;
public static final int INTROSPECTION_INNER = 10;
public static final int STRUCT_OUTER = 100;
public static final int STRUCT_INNER = 10;
public static final int LIST_OUTER = 100;
public static final int LIST_INNER = 10;
public static final int LIST_LENGTH = 100;
public static final int MAP_OUTER = 100;
public static final int MAP_INNER = 10;
public static final int MAP_LENGTH = 100;
public static final int ARRAY_OUTER = 100;
public static final int ARRAY_INNER = 10;
public static final int ARRAY_LENGTH = 1000;
public static final int STRING_ARRAY_OUTER = 10;
public static final int STRING_ARRAY_INNER = 1;
public static final int STRING_ARRAY_LENGTH = 20000;
public static class Log
{
private long last;
private int[] deltas;
private int current = 0;
public Log(int size)
{
deltas = new int[size];
}
public void start()
{
last = System.currentTimeMillis();
}
public void stop()
{
deltas[current] = (int) (System.currentTimeMillis()-last);
current++;
}
public double mean()
{
if (0 == current) return 0;
long sum = 0;
for (int i = 0; i < current; i++)
sum+=deltas[i];
return sum /= current;
}
public long min()
{
int m = Integer.MAX_VALUE;
for (int i = 0; i < current; i++)
if (deltas[i] < m) m = deltas[i];
return m;
}
public long max()
{
int m = 0;
for (int i = 0; i < current; i++)
if (deltas[i] > m) m = deltas[i];
return m;
}
public double stddev()
{
double mean = mean();
double sum = 0;
for (int i=0; i < current; i++)
sum += (deltas[i]-mean)*(deltas[i]-mean);
return Math.sqrt(sum / (current-1));
}
}
public static void main(String[] args)
{
try {
if (0==args.length) {
System.out.println("You must specify a profile type.");
System.out.println("Syntax: profile <pings|arrays|introspect|maps|bytes|lists|structs|signals|rate|strings>");
System.exit(1);
}
DBusConnection conn = DBusConnection.getConnection(DBusConnection.SESSION);
conn.requestBusName("org.freedesktop.DBus.java.profiler");
if ("pings".equals(args[0])) {
int count = PING_INNER*PING_OUTER;
System.out.print("Sending "+count+" pings...");
Peer p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Peer.class);
Log l = new Log(count);
long t = System.currentTimeMillis();
for (int i = 0; i < PING_OUTER; i++) {
for (int j = 0; j < PING_INNER; j++) {
l.start();
p.Ping();
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
} else if ("strings".equals(args[0])) {
int count = STRING_ARRAY_INNER*STRING_ARRAY_OUTER;
System.out.print("Sending array of "+STRING_ARRAY_LENGTH+" strings "+count+" times.");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
String[] v = new String[STRING_ARRAY_LENGTH];
Random r = new Random();
for (int i = 0; i < STRING_ARRAY_LENGTH; i++) v[i] = ""+r.nextInt();
Log l = new Log(count);
long t = System.currentTimeMillis();
for (int i = 0; i < STRING_ARRAY_OUTER; i++) {
for (int j = 0; j < STRING_ARRAY_INNER; j++) {
l.start();
p.stringarray(v);
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
} else if ("arrays".equals(args[0])) {
int count = ARRAY_INNER*ARRAY_OUTER;
System.out.print("Sending array of "+ARRAY_LENGTH+" ints "+count+" times.");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
int[] v = new int[ARRAY_LENGTH];
Random r = new Random();
for (int i = 0; i < ARRAY_LENGTH; i++) v[i] = r.nextInt();
Log l = new Log(count);
long t = System.currentTimeMillis();
for (int i = 0; i < ARRAY_OUTER; i++) {
for (int j = 0; j < ARRAY_INNER; j++) {
l.start();
p.array(v);
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
} else if ("maps".equals(args[0])) {
int count = MAP_INNER*MAP_OUTER;
System.out.print("Sending map of "+MAP_LENGTH+" string=>strings "+count+" times.");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
HashMap<String,String> m = new HashMap<String,String>();
for (int i = 0; i < MAP_LENGTH; i++)
m.put(""+i, "hello");
Log l = new Log(count);
long t = System.currentTimeMillis();
for (int i = 0; i < MAP_OUTER; i++) {
for (int j=0; j < MAP_INNER; j++) {
l.start();
p.map(m);
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
} else if ("lists".equals(args[0])) {
int count = LIST_OUTER*LIST_INNER;
System.out.print("Sending list of "+LIST_LENGTH+" strings "+count+" times.");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
Vector<String> v = new Vector<String>();
for (int i = 0; i < LIST_LENGTH; i++)
v.add("hello "+i);
Log l = new Log(count);
long t = System.currentTimeMillis();
for (int i = 0; i < LIST_OUTER; i++) {
for (int j=0; j < LIST_INNER; j++) {
l.start();
p.list(v);
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
} else if ("structs".equals(args[0])) {
int count = STRUCT_OUTER*STRUCT_INNER;
System.out.print("Sending a struct "+count+" times.");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
ProfileStruct ps = new ProfileStruct("hello", new UInt32(18), 500L);
Log l = new Log(count);
long t = System.currentTimeMillis();
for (int i = 0; i < STRUCT_OUTER; i++) {
for (int j=0; j < STRUCT_INNER; j++) {
l.start();
p.struct(ps);
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
} else if ("introspect".equals(args[0])) {
int count = INTROSPECTION_OUTER*INTROSPECTION_INNER;
System.out.print("Recieving introspection data "+count+" times.");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Introspectable is = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Introspectable.class);
Log l = new Log(count);
long t = System.currentTimeMillis();
String s = null;
for (int i = 0; i < INTROSPECTION_OUTER; i++) {
for (int j = 0; j < INTROSPECTION_INNER; j++) {
l.start();
s = is.Introspect();
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
System.out.println("Introspect data: "+s);
} else if ("bytes".equals(args[0])) {
System.out.print("Sending "+BYTES+" bytes");
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
byte[] bs = new byte[BYTES];
for (int i = 0; i < BYTES; i++)
bs[i] = (byte) i;
long t = System.currentTimeMillis();
p.bytes(bs);
System.out.println(" done in "+(System.currentTimeMillis()-t)+"ms.");
} else if ("rate".equals(args[0])) {
ProfilerInstance pi = new ProfilerInstance();
conn.exportObject("/Profiler", pi);
Profiler p = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Profiler.class);
Peer peer = conn.getRemoteObject("org.freedesktop.DBus.java.profiler", "/Profiler", Peer.class);
long start = System.currentTimeMillis();
int count = 0;
do {
peer.Ping();
count++;
} while(count < 10000);
long end = System.currentTimeMillis();
System.out.println("No payload: "+((count*1000)/(end-start))+" RT/second");
int len = 256;
while (len <= 32768) {
byte[] bs = new byte[len];
count = 0;
start = System.currentTimeMillis();
do {
p.bytes(bs);
count++;
} while(count < 1000);
end = System.currentTimeMillis();
long ms = end-start;
double cps = (count*1000)/ms;
double rate = (len*cps)/(1024.0*1024.0);
System.out.println(len+" byte array) "+(count*len)+" bytes in "+ms+"ms (in "+count+" calls / "+(int)cps+" CPS): "+rate+"MB/s");
len <<= 1;
}
len = 256;
while (len <= 32768) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) sb.append('a');
String s = sb.toString();
end = System.currentTimeMillis()+500;
count = 0;
do {
p.string(s);
count++;
} while(count < 1000);
long ms = end-start;
double cps = (count*1000)/ms;
double rate = (len*cps)/(1024.0*1024.0);
System.out.println(len+" string) "+(count*len)+" bytes in "+ms+"ms (in "+count+" calls / "+(int)cps+" CPS): "+rate+"MB/s");
len <<= 1;
}
} else if ("signals".equals(args[0])) {
int count = SIGNAL_OUTER*SIGNAL_INNER;
System.out.print("Sending "+count+" signals");
ProfileHandler ph = new ProfileHandler();
conn.addSigHandler(Profiler.ProfileSignal.class, ph);
Log l = new Log(count);
Profiler.ProfileSignal ps = new Profiler.ProfileSignal("/");
long t = System.currentTimeMillis();
for (int i = 0; i < SIGNAL_OUTER; i++) {
for (int j = 0; j < SIGNAL_INNER; j++) {
l.start();
conn.sendSignal(ps);
l.stop();
}
System.out.print(".");
}
t = System.currentTimeMillis()-t;
System.out.println(" done.");
System.out.println("min/max/avg (ms): "+l.min()+"/"+l.max()+"/"+l.mean());
System.out.println("deviation: "+l.stddev());
System.out.println("Total time: "+t+"ms");
while (ph.c < count) try { Thread.sleep(100); }
catch (InterruptedException Ie) {};
} else {
conn.disconnect();
System.out.println("Invalid profile ``"+args[0]+"''.");
System.out.println("Syntax: profile <pings|arrays|introspect|maps|bytes|lists|structs|signals>");
System.exit(1);
}
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}