From 2214b48aa06b2a43b932e13e1d2719f8c9ee2b2e Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Fri, 20 Feb 2015 15:53:12 -0500 Subject: [PATCH] INT-3653: Fix Mean Calculations JIRA: https://jira.spring.io/browse/INT-3653 After moving to nanosecond precision, the mean calculations were incorrect. Add test cases to verify correctness. --- .../ExponentialMovingAverageRate.java | 2 +- .../ExponentialMovingAverageRatio.java | 4 ++-- .../ExponentialMovingAverageRateTests.java | 15 +++++++++++++ .../ExponentialMovingAverageRatioTests.java | 15 +++++++++++++ .../ExponentialMovingAverageTests.java | 22 +++++++++++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRate.java b/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRate.java index 3365cc4734..23b4642332 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRate.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRate.java @@ -124,7 +124,7 @@ public class ExponentialMovingAverageRate { } long delta = System.nanoTime() - t0; double value = delta > 0 ? delta / period : 0; - return count / (count / rates.getMeanNanos() + value); + return count / (count / rates.getMean() + value); } /** diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRatio.java b/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRatio.java index 1ce9f6b01d..e3414ab964 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRatio.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/management/ExponentialMovingAverageRatio.java @@ -95,7 +95,7 @@ public class ExponentialMovingAverageRatio { t0 = t; sum = alpha * sum + value; weight = alpha * weight + 1; - cumulative.appendNanos(sum / weight); + cumulative.append(sum / weight); } /** @@ -130,7 +130,7 @@ public class ExponentialMovingAverageRatio { } long t = System.nanoTime(); double alpha = Math.exp((t0 - t) / 1000000. * lapse); - return alpha * cumulative.getMeanNanos() + 1 - alpha; + return alpha * cumulative.getMean() + 1 - alpha; } /** diff --git a/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRateTests.java b/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRateTests.java index 97751fdaf5..de5be40888 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRateTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRateTests.java @@ -22,6 +22,7 @@ import org.junit.Ignore; import org.junit.Test; import org.springframework.integration.test.util.TestUtils; +import org.springframework.util.StopWatch; /** * @author Dave Syer @@ -126,4 +127,18 @@ public class ExponentialMovingAverageRateTests { assertEquals(0, history.getMax(), 0.01); } + @Test + public void testRate() { + ExponentialMovingAverageRate rate = new ExponentialMovingAverageRate(1, 60, 10); + int count = 1000000; + StopWatch watch = new StopWatch(); + watch.start(); + for (int i = 0; i < count; i++) { + rate.increment(); + } + watch.stop(); + double calculatedRate = count / (double) watch.getTotalTimeMillis() * 1000; + assertEquals(calculatedRate, rate.getMean(), 2000000); + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRatioTests.java b/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRatioTests.java index cbaaab2a89..2591ba4f39 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRatioTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageRatioTests.java @@ -130,4 +130,19 @@ public class ExponentialMovingAverageRatioTests { return sum / count; } + @Test + public void testRatio() { + ExponentialMovingAverageRatio ratio = new ExponentialMovingAverageRatio(60, 10); + for (int i = 0; i < 10000; i++) { + if (i % 10 == 0) { + ratio.failure(); + } + else { + ratio.success(); + } + } + assertEquals(0.9, ratio.getMax(), 0.01); + assertEquals(0.9, ratio.getMean(), 0.01); + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageTests.java b/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageTests.java index 4cea8cfe4f..ef43aac7a6 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/support/management/ExponentialMovingAverageTests.java @@ -65,4 +65,26 @@ public class ExponentialMovingAverageTests { assertEquals(String.format("[N=%d, min=%f, max=%f, mean=%f, sigma=%f]", 0, 0d, 0d, 0d, 0d), history.toString()); } + @Test + public void testAv() throws Exception { + ExponentialMovingAverage av = new ExponentialMovingAverage(10); + for (int i = 0; i < 10000; i++) { + switch (i % 3) { + case 0: + av.appendNanos(20000); + break; + case 1: + av.appendNanos(30000); + break; + case 2: + av.appendNanos(40000); + break; + } + } + assertEquals(0.04, av.getMax(), 0.001); + assertEquals(0.02, av.getMin(), 0.001); + assertEquals(0.03, av.getMean(), 0.001); + } + + }