1) The misfeature: The percentiles that ab prints to stdout do not match the values it prints to the .csv file. Lines 1157-1158 of the current trunk version of ab.c: printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], ap_round_ms(stats[(unsigned long)done * percs[i] / 100].time)); and line 1175: t = ap_double_ms(stats[(unsigned long) (0.5 + (double)done * i / 100.0)].time); This was introduced by revision 1617913 (which fixed a nastier bug.) 2) The first bug: The second calculation overruns the end of the array if "done" is small. For instance (assuming a working local server): ab -e foo.txt -n 5 http://localhost/index.html Notice that the last few lines of foo.txt are junk. 3) The second bug: The first calculation still has the potential to overflow and mess up the index on a 32 bit machine (see revision 1617913), though it would take "done" >= 2^32 * 100/99 or so (around 4.5 million) and the data would fill and maybe overflow a 32 bit address space. My take on possible solutions: A) Use (unsigned long)((double)done * percs[i] / 100.0) as the subscript in the first case and (unsigned long)((double)done * i / 100.0) as the subscript in the second case. This is essentially the "nearest rank method." (See for example the Wikipedia article on percentiles.) The difference is that the mapping from percentiles to indices is right open and left closed when "done" is small. B) Use (unsigned long)ceil((double)done * percs[i] / 100.0) - 1 (percs[i] > 0) as the subscript in the first case and (unsigned long)ceil((double)done * i / 100.0) - 1 (i > 0) as the subscript in the second case. This is a bit ugly, but the mapping from percentiles to indices is now left open and right closed when "done" is small. A special case is necessary when the desired percentile is zero. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx For additional commands, e-mail: users-help@xxxxxxxxxxxxxxxx