/* 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); } } }