[httperf] percentile output of response times

Steffen Kiefer steffen.kiefer at webde.de
Wed Jan 23 02:11:54 PST 2008


Hi,

i would like to contribute an additional feature for httperf.
Following patch calculates percentage values of response times and 
finally prints them within the summary output in precision of milliseconds.
I would be pleased if you added this patch to the source tree.

Thanks in advance

Steffen

-- 
Steffen Kiefer
Softwareentwickler

1 & 1 Internet AG
Brauerstraße 48  -   D-76135 Karlsruhe
Tel. +49-721-91374-4884  Fax +49-721-91374-2740
steffen.kiefer at webde.de  http://www.web.de/

Amtsgericht Montabaur HRB 6484
Vorstand: Henning Ahlert, Ralph Dommermuth, Matthias Ehrlich, Andreas 
Gauger, Thomas Gottschlich, Matthias Greve, Robert Hoffmann, Norbert 
Lang, Achim Weiss
Aufsichtsratsvorsitzender: Michael Scheeren
-------------- next part --------------
--- httperf-0.9.0_orig/src/stat/basic.c	2007-04-07 09:01:56.000000000 +0200
+++ httperf-0.9.0_patched/src/stat/basic.c	2008-01-23 10:42:00.000000000 +0100
@@ -83,6 +83,7 @@
 
     u_int num_responses;
     Time call_response_sum;	/* sum of response times */
+    Time call_response_time_max; /* maximum response time */
 
     Time call_xfer_sum;		/* sum of response times */
 
@@ -95,6 +96,7 @@
     u_wide footer_bytes_received;	/* sum of all footer bytes */
 
     u_int conn_lifetime_hist[NUM_BINS];	/* histogram of connection lifetimes */
+    u_int response_time_hist[NUM_BINS];	/* histogram of response times */
   }
 basic;
 
@@ -254,12 +256,23 @@
 {
   Call *c = (Call *) obj;
   Time now;
+  u_int bin;
 
   assert (et == EV_CALL_RECV_START && object_is_call (c));
 
   now = timer_now ();
+  Time response_time = (now - c->basic.time_send_start);
+
+  // create histogramm of response times
+  bin = response_time*NUM_BINS/MAX_LIFETIME;
+  if (bin >= NUM_BINS) 
+    bin = NUM_BINS;
+  ++basic.response_time_hist[bin];
+
+  if (response_time > basic.call_response_time_max)
+    basic.call_response_time_max = response_time;
 
-  basic.call_response_sum += now - c->basic.time_send_start;
+  basic.call_response_sum += response_time;
   c->basic.time_recv_start = now;
   ++basic.num_responses;
 }
@@ -316,6 +329,9 @@
   Time conn_time = 0.0, resp_time = 0.0, xfer_time = 0.0;
   Time call_size = 0.0, hdr_size = 0.0, reply_size = 0.0, footer_size = 0.0;
   Time lifetime_avg = 0.0, lifetime_stddev = 0.0, lifetime_median = 0.0;
+  Time replytime_median = 0.0, replytime_66 = 0.0, replytime_75 = 0.0, replytime_80 = 0.0, 
+       replytime_90 = 0.0, replytime_95 = 0.0, replytime_98 = 0.0, replytime_99 = 0.0, replytime_100 = 0.0;
+
   double reply_rate_avg = 0.0, reply_rate_stddev = 0.0;
   int i, total_replies = 0;
   Time delta, user, sys;
@@ -354,6 +370,7 @@
 	  "<=%u concurrent connections)\n",
 	  basic.num_conns_issued / delta, 1e3*conn_period, basic.max_conns);
 
+
   if (basic.num_lifetimes > 0)
     {
       lifetime_avg = (basic.conn_lifetime_sum / basic.num_lifetimes);
@@ -412,12 +429,47 @@
 	  reply_rate_stddev, basic.num_reply_rates);
 
   if (basic.num_responses > 0)
+  {
     resp_time = basic.call_response_sum / basic.num_responses;
-  if (total_replies > 0)
+    // determine response time percentiles
+    n = 0;
+    int numbucks = 0;
+    for (i = 0; i < NUM_BINS; ++i) 
+    {
+      n += basic.response_time_hist[i];
+      if (n >= (float) (0.5 * basic.num_responses) && replytime_median == 0.0)
+        replytime_median = i * BIN_WIDTH;
+      if (n >= (float) (0.66 * basic.num_responses) && replytime_66 == 0.0)
+        replytime_66 = i * BIN_WIDTH;
+      if (n >= (float) (0.75 * basic.num_responses) && replytime_75 == 0.0)
+        replytime_75 = i * BIN_WIDTH;
+      if (n >= (float) (0.8 * basic.num_responses) && replytime_80 == 0.0)
+        replytime_80 = i * BIN_WIDTH;
+      if (n >= (float) (0.9 * basic.num_responses) && replytime_90 == 0.0) 
+        replytime_90 = i * BIN_WIDTH;
+      if (n >= (float) (0.95 * basic.num_responses) && replytime_95 == 0.0) 
+        replytime_95 = i * BIN_WIDTH;
+      if (n >= (float) (0.98 * basic.num_responses) && replytime_98 == 0.0) 
+        replytime_98 = i * BIN_WIDTH;
+      if (n >= (float) (0.99 * basic.num_responses) && replytime_99 == 0.0) 
+        replytime_99 = i * BIN_WIDTH;
+    }
+  }
+
+  if (total_replies > 0) 
     xfer_time = basic.call_xfer_sum / total_replies;
   printf ("Reply time [ms]: response %.1f transfer %.1f\n",
 	  1e3*resp_time, 1e3*xfer_time);
 
+  if (total_replies > 1)
+      printf("\nPercentages of the requests served within a certain time (ms) :\n"
+             "   50%%: %8.0f\n   66%%: %8.0f\n   75%%: %8.0f\n"
+             "   80%%: %8.0f\n   90%%: %8.0f\n   95%%: %8.0f\n"
+             "   98%%: %8.0f\n   99%%: %8.0f\n  100%%: %8.0f\n\n", 
+              replytime_median * 1000, replytime_66 * 1000, replytime_75 * 1000, 
+              replytime_80 * 1000, replytime_90 * 1000, replytime_95 * 1000,
+              replytime_98 * 1000, replytime_99 * 1000, basic.call_response_time_max * 1000); 
+
   if (total_replies)
     {
       hdr_size = basic.hdr_bytes_received / total_replies;


More information about the httperf mailing list