From: <tk...@hy...> - 2008-04-15 18:50:11
|
Author: tkeeney Date: 2008-04-15 11:49:57 -0700 (Tue, 15 Apr 2008) New Revision: 8903 URL: http://svn.hyperic.org/?view=rev&root=Hyperic+HQ&revision=8903 Modified: branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup.java branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup_test.java Log: [HHQ-1672] Added synchronous metric evaluation. Based on localized performance tests implemented inside the unit test, synchronous evaluation appears to be faster than asynchronous evaluation. Modified: branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup.java =================================================================== --- branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup.java 2008-04-15 18:22:51 UTC (rev 8902) +++ branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup.java 2008-04-15 18:49:57 UTC (rev 8903) @@ -37,7 +37,10 @@ * internal queue such that the metric values in the group will be updated * only after the internal queue is flushed. Flushing occurs automatically * when the queue capacity is reached but it may be invoked explicitly by any - * client wishing to obtain the most recent snapshot of metrics. + * client wishing to obtain the most recent snapshot of metrics. Clients may + * also choose to update the metric values in the group synchronously when a + * new method invocation time value is added. In this case, the internal queue + * and flush operations are not used. * * Each metric in the group (num invocations/max,min,avg invocation time) is * guaranteed to be consistent with the current flushed state of the group. @@ -130,6 +133,17 @@ flush(latestInvocationTime, true); } } + + /** + * Add an invocation time and update the metrics in the group immediately. + * + * @param invocationTime The invocation time. + */ + public void addInvocationTimeSynch(long invocationTime) { + synchronized (_lock) { + updateMetrics(invocationTime); + } + } /** * Flush the metric group, updating the metrics in the group with the Modified: branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup_test.java =================================================================== --- branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup_test.java 2008-04-15 18:22:51 UTC (rev 8902) +++ branches/HQ_3_2/src/org/hyperic/hq/common/MethodInvocationMetricsGroup_test.java 2008-04-15 18:49:57 UTC (rev 8903) @@ -122,6 +122,21 @@ assertEquals(1.5, metricsGroup.getAverageInvocationTime(), 0.0); } + public void testAddInvocationsSynchronously() { + MethodInvocationMetricsGroup metricsGroup = + new MethodInvocationMetricsGroup(null); + + metricsGroup.addInvocationTimeSynch(0); + metricsGroup.addInvocationTimeSynch(1); + metricsGroup.addInvocationTimeSynch(2); + metricsGroup.addInvocationTimeSynch(3); + + assertEquals(4, metricsGroup.getNumberInvocations()); + assertEquals(3, metricsGroup.getMaxInvocationTime()); + assertEquals(0, metricsGroup.getMinInvocationTime()); + assertEquals(1.5, metricsGroup.getAverageInvocationTime(), 0.0); + } + public void testAddInvocationsFlushExplicitly() { MethodInvocationMetricsGroup metricsGroup = new MethodInvocationMetricsGroup(null); @@ -208,7 +223,99 @@ assertNoMetrics(metricsGroup); } + /** + * Test the performance of adding method invocation times synchronously, + * evaluating the group metrics immediately. + */ + public void testSynchInsertionPerformance() throws Exception { + MethodInvocationMetricsGroup metricsGroup = + new MethodInvocationMetricsGroup(null); + + int numThreads = 10; + int numInserts = 100000; + + InsertionThread[] threads = new InsertionThread[numThreads]; + + for (int i = 0; i < threads.length; i++) { + threads[i] = new InsertionThread(metricsGroup, numInserts, false); + } + + long start = System.currentTimeMillis(); + + for (int i = 0; i < threads.length; i++) { + threads[i].start(); + } + + for (int i = 0; i < threads.length; i++) { + threads[i].join(); + } + + System.out.println("total insert time (sync): "+(System.currentTimeMillis()-start)); + } + /** + * Test the performance of adding method invocation times asynchronously, + * evaluating the group metrics only on flush. + */ + public void testAsyncInsertionPerformance() throws Exception { + MethodInvocationMetricsGroup metricsGroup = + new MethodInvocationMetricsGroup(null); + + int numThreads = 10; + int numInserts = 100000; + + InsertionThread[] threads = new InsertionThread[numThreads]; + + for (int i = 0; i < threads.length; i++) { + threads[i] = new InsertionThread(metricsGroup, numInserts, true); + } + + long start = System.currentTimeMillis(); + + for (int i = 0; i < threads.length; i++) { + threads[i].start(); + } + + for (int i = 0; i < threads.length; i++) { + threads[i].join(); + } + + System.out.println("total insert time (async): "+(System.currentTimeMillis()-start)); + } + + private static class InsertionThread extends Thread { + + private final MethodInvocationMetricsGroup _metricsGroup; + private final int _numInserts; + private final boolean _async; + + public InsertionThread(MethodInvocationMetricsGroup metricsGroup, + int numInserts, + boolean async) { + super("Insertion Thread"); + setDaemon(true); + _metricsGroup = metricsGroup; + _numInserts = numInserts; + _async = async; + } + + public void run() { + for (int i = 0; i < _numInserts; i++) { + + if (_async) { + _metricsGroup.addInvocationTime(i); + } else { + _metricsGroup.addInvocationTimeSynch(i); + } + } + + if (_async) { + _metricsGroup.flush(); + } + } + } + + private void assertNoMetrics(MethodInvocationMetricsGroup metricsGroup) { assertEquals(0, metricsGroup.getNumberInvocations()); assertEquals(0, metricsGroup.getMaxInvocationTime()); |