| package kellegous.client; |
| |
| import com.google.gwt.core.client.Duration; |
| import com.google.gwt.core.client.EntryPoint; |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.dom.client.DivElement; |
| import com.google.gwt.dom.client.Document; |
| import com.google.gwt.user.client.Command; |
| import com.google.gwt.user.client.Event; |
| import com.google.gwt.user.client.EventListener; |
| |
| public class Dispatch implements EntryPoint { |
| private static native Event createMockEvent() /*-{ |
| return { type: "click" }; |
| }-*/; |
| |
| private static double[] runTrial(int numberOfObservers, |
| int numberOfIterations, int numberOfSamples) { |
| final double[] results = new double[numberOfSamples]; |
| final EventListener subject = Subject.create(numberOfObservers); |
| final Event event = createMockEvent(); |
| for (int j = 0; j < numberOfSamples; ++j) { |
| final Duration d = new Duration(); |
| for (int i = 0; i < numberOfIterations; ++i) { |
| subject.onBrowserEvent(event); |
| } |
| results[j] = d.elapsedMillis(); |
| } |
| return results; |
| } |
| |
| private static native void schedule(Command command) /*-{ |
| $wnd.setTimeout(function() { |
| command.@com.google.gwt.user.client.Command::execute()(); |
| }, 0); |
| }-*/; |
| |
| // t-distribution for p = 0.05 (used to compute 95% confidence intervals). |
| // This table is based at df = 2. |
| private final static double[] TDIST = new double[] { |
| 4.3027, 3.1824, 2.7765, 2.5706, 2.4469, 2.3646, 2.3060, 2.2622, 2.2281, |
| 2.2010, 2.1788, 2.1604, 2.1448, 2.1315, 2.1199, 2.1098, 2.1009, 2.0930, |
| 2.0860, 2.0796, 2.0739, 2.0687, 2.0639, 2.0595, 2.0555, 2.0518, 2.0484, |
| 2.0452, 2.0423, 2.0395, 2.0369, 2.0345, 2.0322, 2.0301, 2.0281, 2.0262, |
| 2.0244, 2.0227, 2.0211, 2.0195, 2.0181, 2.0167, 2.0154, 2.0141, 2.0129, |
| 2.0117, 2.0106, 2.0096, 2.0086, 2.0076, 2.0066, 2.0057, 2.0049, 2.0040, |
| 2.0032, 2.0025, 2.0017, 2.0010, 2.0003, 1.9996, 1.9990, 1.9983, 1.9977, |
| 1.9971, 1.9966, 1.9960, 1.9955, 1.9949, 1.9944, 1.9939, 1.9935, 1.9930, |
| 1.9925, 1.9921, 1.9917, 1.9913, 1.9908, 1.9905, 1.9901, 1.9897, 1.9893, |
| 1.9890, 1.9886, 1.9883, 1.9879, 1.9876, 1.9873, 1.9870, 1.9867, 1.9864, |
| 1.9861, 1.9858, 1.9855, 1.9852, 1.9850, 1.9847, 1.9845, 1.9842, 1.9840}; |
| |
| private static double computeT(int df) { |
| return TDIST[df - 2]; |
| } |
| |
| private static double computeMean(double[] s) { |
| double sum = 0.0; |
| final int n = s.length; |
| for (int i = 0; i < n; ++i) { |
| sum += s[i]; |
| } |
| return sum / n; |
| } |
| |
| private static double computeStandardError(double[] data, double mean) { |
| final int n = data.length; |
| double sum = 0.0; |
| for (int i = 0; i < n; ++i) { |
| final double d = data[i] - mean; |
| sum += d * d; |
| } |
| |
| return Math.sqrt(sum / n) / Math.sqrt(n); |
| } |
| |
| private static class Stats { |
| private final double mean, upper, lower; |
| |
| Stats(double[] data) { |
| mean = computeMean(data); |
| final double error = computeStandardError(data, mean); |
| final double t = computeT(data.length - 1); |
| upper = mean + t * error; |
| lower = mean - t * error; |
| } |
| |
| @Override |
| public String toString() { |
| return mean + ", " + lower + ", " + upper; |
| } |
| } |
| |
| public static class Runner { |
| private int n; |
| private final int max, numIterations, numSamples; |
| private Stats[] results; |
| |
| Runner(int min, int max, int numIterations, int numSamples) { |
| n = min; |
| this.max = max; |
| this.numIterations = numIterations; |
| this.numSamples = numSamples; |
| results = new Stats[max - min + 1]; |
| } |
| |
| void finish() { |
| final Document document = Document.get(); |
| final DivElement root = document.createDivElement(); |
| document.getBody().appendChild(root); |
| for (int i = 0, n = results.length; i < n; ++i) { |
| final DivElement div = document.createDivElement(); |
| root.appendChild(div); |
| div.setInnerText("" + results[i].toString()); |
| } |
| } |
| |
| void next() { |
| schedule(new Command() { |
| public void execute() { |
| final double[] results = runTrial(n, numIterations, numSamples); |
| Runner.this.results[n] = new Stats(results); |
| if (++n <= max) { |
| next(); |
| } else { |
| finish(); |
| } |
| } |
| }); |
| } |
| |
| void run() { |
| next(); |
| } |
| } |
| |
| public void onModuleLoad() { |
| // Don't run this in hosted mode. |
| if (GWT.isScript()) { |
| new Runner(0, 10, 10000, 20).run(); |
| } |
| } |
| } |