Hello,
  I've evaluated using JMeter a couple of times in the past, but haven't
actually used it for any real work until now.  I've encountered (and
fixed) a couple of bugs.  Here's the first one -- I'll try to get the
others cleaned up and posted in the next few days.  I haven't
contributed to Apache projects before, so please let me know if I need
to do something differently in the future.

The calculation of the standard deviation in
org.apache.jmeter.visualizers.GraphModel is incorrect.  It maintains a
running sum of the square of the difference between the sample value and
the average, and then uses this to calculate the deviation.  This is
incorrect, since the average at the time this sample is added is not the
same as the average when the next sample is added.

Here's an example to illustrate the problem.  Let's assume we have 5
data points: 20, 80, 40, 100, 120.  Here is what JMeter will calculate
at each point:

#    Value    Average    Deviation    Correct Deviation
1:   20       20         0            0
2:   80       50         21           21
3:   40       47         18           25
4:   100      60         25           32
5:   120      72         31           37

The correct way to calculate the standard deviation as values are added
is to keep a running sum of the samples and the sum of the squares. 
Then the variance is the mean of the squares minus the square of the
mean, and the standard deviation is the square root of the variance.

The attached patch should calculate the standard deviation correctly.

Jeremy
Index: jakarta-jmeter/src/components/org/apache/jmeter/visualizers/GraphModel.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-jmeter/src/components/org/apache/jmeter/visualizers/GraphModel.java,v
retrieving revision 1.3
diff -u -r1.3 GraphModel.java
--- jakarta-jmeter/src/components/org/apache/jmeter/visualizers/GraphModel.java 3 Feb 
2003 14:29:00 -0000       1.3
+++ jakarta-jmeter/src/components/org/apache/jmeter/visualizers/GraphModel.java 5 Feb 
+2003 14:24:51 -0000
@@ -2,7 +2,7 @@
  *  ====================================================================
  *  The Apache Software License, Version 1.1
  *
- *  Copyright (c) 2001 The Apache Software Foundation.  All rights
+ *  Copyright (c) 2001,2003 The Apache Software Foundation.  All rights
  *  reserved.
  *
  *  Redistribution and use in source and binary forms, with or without
@@ -81,8 +81,8 @@
     private String name;
     private List samples;
     private List listeners;
-    private long averageSum = 0;
-    private long variationSum = 0;
+    private long sum = 0;
+    private long sumOfSquares = 0;
     private long counter = 0;
     private long previous = 0;
     private long max = 1;
@@ -247,8 +247,8 @@
     public void clear()
     {
         samples.clear();
-        averageSum = 0;
-        variationSum = 0;
+        sum = 0;
+        sumOfSquares = 0;
         counter = 0;
         previous = 0;
         max = 1;
@@ -310,11 +310,18 @@
         {
             max = sample;
         }
-        averageSum += sample;
-        long average = averageSum / ++counter;
 
-        variationSum += Math.pow(sample - average, 2);
-        long deviation = (long) Math.pow(variationSum / counter, 0.5);
+        counter++;
+
+        sum += sample;
+        float average = ((float)sum) / counter;
+
+        sumOfSquares += sample * sample;
+        // Standard deviation is the mean of the squares minus the square
+        // of the mean
+        long deviation = (long)Math.sqrt(
+               (sumOfSquares / counter) - average * average);
+
         float throughput = 0;
 
         if (timeStamp - startTime > 0)
@@ -330,14 +337,15 @@
         if (average > graphMax)
         {
             bigChange = true;
-            graphMax = average * 3;
+            graphMax = (long)average * 3;
         }
         if (deviation > graphMax)
         {
             bigChange = true;
             graphMax = deviation * 3;
         }
-        Sample s = new Sample(sample, average, deviation, throughput, !success);
+        Sample s = new Sample(sample, (long)average, deviation,
+                        throughput, !success);
 
         previous = sample;
         current = s;


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to