📄 ab.c
字号:
mincon = ap_min(mincon, s.ctime); mintot = ap_min(mintot, s.time); mind = ap_min(mind, s.time - s.ctime); minwait = ap_min(minwait, s.waittime); maxcon = ap_max(maxcon, s.ctime); maxtot = ap_max(maxtot, s.time); maxd = ap_max(maxd, s.time - s.ctime); maxwait = ap_max(maxwait, s.waittime); totalcon += s.ctime; total += s.time; totald += s.time - s.ctime; totalwait += s.waittime; } meancon = totalcon / requests; meantot = total / requests; meand = totald / requests; meanwait = totalwait / requests; /* calculating the sample variance: the sum of the squared deviations, divided by n-1 */ for (i = 0; i < requests; i++) { struct data s = stats[i]; double a; a = ((double)s.time - meantot); sdtot += a * a; a = ((double)s.ctime - meancon); sdcon += a * a; a = ((double)s.time - (double)s.ctime - meand); sdd += a * a; a = ((double)s.waittime - meanwait); sdwait += a * a; } sdtot = (requests > 1) ? sqrt(sdtot / (requests - 1)) : 0; sdcon = (requests > 1) ? sqrt(sdcon / (requests - 1)) : 0; sdd = (requests > 1) ? sqrt(sdd / (requests - 1)) : 0; sdwait = (requests > 1) ? sqrt(sdwait / (requests - 1)) : 0; if (gnuplot) { FILE *out = fopen(gnuplot, "w"); long i; apr_time_t sttime; char tmstring[1024];/* XXXX */ if (!out) { perror("Cannot open gnuplot output file"); exit(1); } fprintf(out, "starttime\tseconds\tctime\tdtime\tttime\twait\n"); for (i = 0; i < requests; i++) { apr_time_t diff = stats[i].time - stats[i].ctime; sttime = stats[i].starttime; (void) apr_ctime(tmstring, sttime); fprintf(out, "%s\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\n", tmstring, sttime, stats[i].ctime, diff, stats[i].time, stats[i].waittime); } fclose(out); } /* * XXX: what is better; this hideous cast of the compradre function; or * the four warnings during compile ? dirkx just does not know and * hates both/ */ qsort(stats, requests, sizeof(struct data), (int (*) (const void *, const void *)) compradre); if ((requests > 1) && (requests % 2)) mediancon = (stats[requests / 2].ctime + stats[requests / 2 + 1].ctime) / 2; else mediancon = stats[requests / 2].ctime; qsort(stats, requests, sizeof(struct data), (int (*) (const void *, const void *)) compri); if ((requests > 1) && (requests % 2)) mediand = (stats[requests / 2].time + stats[requests / 2 + 1].time \ -stats[requests / 2].ctime - stats[requests / 2 + 1].ctime) / 2; else mediand = stats[requests / 2].time - stats[requests / 2].ctime; qsort(stats, requests, sizeof(struct data), (int (*) (const void *, const void *)) compwait); if ((requests > 1) && (requests % 2)) medianwait = (stats[requests / 2].waittime + stats[requests / 2 + 1].waittime) / 2; else medianwait = stats[requests / 2].waittime; qsort(stats, requests, sizeof(struct data), (int (*) (const void *, const void *)) comprando); if ((requests > 1) && (requests % 2)) mediantot = (stats[requests / 2].time + stats[requests / 2 + 1].time) / 2; else mediantot = stats[requests / 2].time; printf("\nConnection Times (ms)\n"); if (confidence) {#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4d %5.1f %6" APR_TIME_T_FMT " %7" APR_TIME_T_FMT "\n" printf(" min mean[+/-sd] median max\n"); printf("Connect: " CONF_FMT_STRING, mincon, (int) (meancon + 0.5), sdcon, mediancon, maxcon); printf("Processing: " CONF_FMT_STRING, mind, (int) (meand + 0.5), sdd, mediand, maxd); printf("Waiting: " CONF_FMT_STRING, minwait, (int) (meanwait + 0.5), sdwait, medianwait, maxwait); printf("Total: " CONF_FMT_STRING, mintot, (int) (meantot + 0.5), sdtot, mediantot, maxtot);#undef CONF_FMT_STRING#define SANE(what,mean,median,sd) \ { \ double d = (double)mean - median; \ if (d < 0) d = -d; \ if (d > 2 * sd ) \ printf("ERROR: The median and mean for " what " are more than twice the standard\n" \ " deviation apart. These results are NOT reliable.\n"); \ else if (d > sd ) \ printf("WARNING: The median and mean for " what " are not within a normal deviation\n" \ " These results are probably not that reliable.\n"); \ } SANE("the initial connection time", meancon, mediancon, sdcon); SANE("the processing time", meand, mediand, sdd); SANE("the waiting time", meanwait, medianwait, sdwait); SANE("the total time", meantot, mediantot, sdtot); } else { printf(" min avg max\n");#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %5" APR_TIME_T_FMT "%5" APR_TIME_T_FMT "\n" printf("Connect: " CONF_FMT_STRING, mincon, meancon, maxcon); printf("Processing: " CONF_FMT_STRING, mintot - mincon, meantot - meancon, maxtot - maxcon); printf("Total: " CONF_FMT_STRING, mintot, meantot, maxtot);#undef CONF_FMT_STRING } /* Sorted on total connect times */ if (percentile && (requests > 1)) { printf("\nPercentage of the requests served within a certain time (ms)\n"); for (i = 0; i < sizeof(percs) / sizeof(int); i++) if (percs[i] <= 0) printf(" 0%% <0> (never)\n"); else if (percs[i] >= 100) printf(" 100%% %5" APR_TIME_T_FMT " (longest request)\n", stats[requests - 1].time); else printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], stats[(int) (requests * percs[i] / 100)].time); } if (csvperc) { FILE *out = fopen(csvperc, "w"); int i; if (!out) { perror("Cannot open CSV output file"); exit(1); } fprintf(out, "" "Percentage served" "," "Time in ms" "\n"); for (i = 0; i < 100; i++) { apr_time_t t; if (i == 0) t = stats[0].time; else if (i == 100) t = stats[requests - 1].time; else t = stats[(int) (0.5 + requests * i / 100.0)].time; fprintf(out, "%d,%e\n", i, (double)t); } fclose(out); } }}/* --------------------------------------------------------- *//* calculate and output results in HTML */static void output_html_results(void){ long timetaken; endtime = apr_time_now(); timetaken = (long)((endtime - start) / 1000); printf("\n\n<table %s>\n", tablestring); printf("<tr %s><th colspan=2 %s>Server Software:</th>" "<td colspan=2 %s>%s</td></tr>\n", trstring, tdstring, tdstring, servername); printf("<tr %s><th colspan=2 %s>Server Hostname:</th>" "<td colspan=2 %s>%s</td></tr>\n", trstring, tdstring, tdstring, hostname); printf("<tr %s><th colspan=2 %s>Server Port:</th>" "<td colspan=2 %s>%hd</td></tr>\n", trstring, tdstring, tdstring, port); printf("<tr %s><th colspan=2 %s>Document Path:</th>" "<td colspan=2 %s>%s</td></tr>\n", trstring, tdstring, tdstring, path); printf("<tr %s><th colspan=2 %s>Document Length:</th>" "<td colspan=2 %s>%" APR_SIZE_T_FMT " bytes</td></tr>\n", trstring, tdstring, tdstring, doclen); printf("<tr %s><th colspan=2 %s>Concurrency Level:</th>" "<td colspan=2 %s>%d</td></tr>\n", trstring, tdstring, tdstring, concurrency); printf("<tr %s><th colspan=2 %s>Time taken for tests:</th>" "<td colspan=2 %s>%" APR_INT64_T_FMT ".%03ld seconds</td></tr>\n", trstring, tdstring, tdstring, apr_time_sec(timetaken), (long)apr_time_usec(timetaken)); printf("<tr %s><th colspan=2 %s>Complete requests:</th>" "<td colspan=2 %s>%ld</td></tr>\n", trstring, tdstring, tdstring, done); printf("<tr %s><th colspan=2 %s>Failed requests:</th>" "<td colspan=2 %s>%ld</td></tr>\n", trstring, tdstring, tdstring, bad); if (bad) printf("<tr %s><td colspan=4 %s > (Connect: %d, Length: %d, Exceptions: %d)</td></tr>\n", trstring, tdstring, err_conn, err_length, err_except); if (err_response) printf("<tr %s><th colspan=2 %s>Non-2xx responses:</th>" "<td colspan=2 %s>%d</td></tr>\n", trstring, tdstring, tdstring, err_response); if (keepalive) printf("<tr %s><th colspan=2 %s>Keep-Alive requests:</th>" "<td colspan=2 %s>%ld</td></tr>\n", trstring, tdstring, tdstring, doneka); printf("<tr %s><th colspan=2 %s>Total transferred:</th>" "<td colspan=2 %s>%ld bytes</td></tr>\n", trstring, tdstring, tdstring, totalread); if (posting > 0) printf("<tr %s><th colspan=2 %s>Total POSTed:</th>" "<td colspan=2 %s>%ld</td></tr>\n", trstring, tdstring, tdstring, totalposted); printf("<tr %s><th colspan=2 %s>HTML transferred:</th>" "<td colspan=2 %s>%ld bytes</td></tr>\n", trstring, tdstring, tdstring, totalbread); /* avoid divide by zero */ if (timetaken) { printf("<tr %s><th colspan=2 %s>Requests per second:</th>" "<td colspan=2 %s>%.2f</td></tr>\n", trstring, tdstring, tdstring, 1000 * (float) (done) / timetaken); printf("<tr %s><th colspan=2 %s>Transfer rate:</th>" "<td colspan=2 %s>%.2f kb/s received</td></tr>\n", trstring, tdstring, tdstring, (float) (totalread) / timetaken); if (posting > 0) { printf("<tr %s><td colspan=2 %s> </td>" "<td colspan=2 %s>%.2f kb/s sent</td></tr>\n", trstring, tdstring, tdstring, (float) (totalposted) / timetaken); printf("<tr %s><td colspan=2 %s> </td>" "<td colspan=2 %s>%.2f kb/s total</td></tr>\n", trstring, tdstring, tdstring, (float) (totalread + totalposted) / timetaken); } } { /* work out connection times */ long i; apr_interval_time_t totalcon = 0, total = 0; apr_interval_time_t mincon = AB_MAX, mintot = AB_MAX; apr_interval_time_t maxcon = 0, maxtot = 0; for (i = 0; i < requests; i++) { struct data s = stats[i]; mincon = ap_min(mincon, s.ctime); mintot = ap_min(mintot, s.time); maxcon = ap_max(maxcon, s.ctime); maxtot = ap_max(maxtot, s.time); totalcon += s.ctime; total += s.time; } if (requests > 0) { /* avoid division by zero (if 0 requests) */ printf("<tr %s><th %s colspan=4>Connnection Times (ms)</th></tr>\n", trstring, tdstring); printf("<tr %s><th %s> </th> <th %s>min</th> <th %s>avg</th> <th %s>max</th></tr>\n", trstring, tdstring, tdstring, tdstring, tdstring); printf("<tr %s><th %s>Connect:</th>" "<td %s>%5" APR_TIME_T_FMT "</td>" "<td %s>%5" APR_TIME_T_FMT "</td>" "<td %s>%5" APR_TIME_T_FMT "</td></tr>\n", trstring, tdstring, tdstring, mincon, tdstring, totalcon / requests, tdstring, maxcon); printf("<tr %s><th %s>Processing:</th>" "<td %s>%5" APR_TIME_T_FMT "</td>" "<td %s>%5" APR_TIME_T_FMT "</td>" "<td %s>%5" APR_TIME_T_FMT "</td></tr>\n", trstring, tdstring, tdstring, mintot - mincon, tdstring, (total / requests) - (totalcon / requests), tdstring, maxtot - maxcon); printf("<tr %s><th %s>Total:</th>" "<td %s>%5" APR_TIME_T_FMT "</td>" "<td %s>%5" APR_TIME_T_FMT "</td>" "<td %s>%5" APR_TIME_T_FMT "</td></tr>\n", trstring, tdstring, tdstring, mintot, tdstring, total / requests, tdstring, maxtot); } printf("</table>\n"); }}/* --------------------------------------------------------- *//* start asnchronous non-blocking connection */static void start_connect(struct connection * c){ apr_status_t rv;#ifdef USE_SSL if (ssl == 1) { ssl_start_connect(c); return; }#endif if (!(started < requests)) return; c->read = 0; c->bread = 0; c->keepalive = 0; c->cbx = 0; c->gotheader = 0; c->rwrite = 0; if (c->ctx) apr_pool_destroy(c->ctx); apr_pool_create(&c->ctx, cntxt); if ((rv = apr_socket_create(&c->aprsock, destsa->family, SOCK_STREAM, c->ctx)) != APR_SUCCESS) { apr_err("socket", rv); } if ((rv = apr_socket_opt_set(c->aprsock, APR_SO_NONBLOCK, 1)) != APR_SUCCESS) { apr_err("socket nonblock", rv); } c->start = apr_time_now(); if ((rv = apr_connect(c->aprsock, destsa)) != APR_SUCCESS) { if (APR_STATUS_IS_EINPROGRESS(rv)) { apr_pollfd_t new_pollfd; c->state = STATE_CONNECTING; c->rwrite = 0; new_pollfd.desc_type = APR_POLL_SOCKET; new_pollfd.reqevents = APR_POLLOUT; new_pollfd.desc.s = c->aprsock; new_pollfd.client_data = c; apr_pollset_add(readbits, &new_pollfd); return; } else { apr_pollfd_t remove_pollfd; remove_pollfd.desc_type = APR_POLL_SOCKET; remove_pollfd.desc.s = c->aprsock; apr_pollset_remove(readbits, &remove_pollfd); apr_socket_close(c->aprsock); err_conn++; if (bad++ > 10) { fprintf(stderr, "\nTest aborted after 10 failures\n\n"); apr_err("apr_connect()", rv); } c->state = STATE_UNCONNECTED; start_connect(c); return; } } /* connected first time */ c->state = STATE_CONNECTED; started++; write_request(c);}/* --------------------------------------------------------- *//* close down connection and save stats */static void close_connection(struct connection * c){ if (c->read == 0 && c->keepalive) { /* * server has legitimately shut down an idle keep alive request */ if (good) good--; /* connection never happened */ } else { if (good == 1) { /* first time here */ doclen = c->bread; } else if (c->bread != doclen) { bad++; err_length++; } /* save out time */ if (done < requests) { struct data s; if ((done) && heartbeatres && !(done % heartbeatres)) { fprintf(stderr, "Completed %ld requests\n", done); fflush(stderr); } c->done = apr_time_now(); s.read = c->read; s.starttime = c->start; s.ctime = (c->connect - c->start) / 1000; s.time = (c->done - c->start) / 1000; s.waittime = (c->beginread - c->endwrite) / 1000; stats[done++] = s; } }#ifdef USE_SSL if (ssl == 1) { SSL_shutdown(c->ssl); SSL_free(c->ssl); } else#endif { apr_pollfd_t remove_pollfd; remove_pollfd.desc_type = APR_POLL_SOCKET; remove_pollfd.desc.s = c->aprsock; apr_pollset_remove(readbits, &remove_pollfd); apr_socket_close(c->aprsock); } c->state = STATE_UNCONNECTED; /* connect again */ start_connect(c); return;}/* --------------------------------------------------------- *//* read data from connection */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -