Skip to content

Commit 4f05ec3

Browse files
committed
wrk show latency
1 parent 771ab9c commit 4f05ec3

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

examples/wrk.cpp

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
*
77
*/
88

9+
#include <vector>
10+
#include <algorithm>
11+
912
#include "hv.h"
1013
#include "hmain.h" // import parse_opt
1114
#include "hloop.h"
@@ -15,19 +18,23 @@
1518
#include "HttpParser.h"
1619
using namespace hv;
1720

18-
static const char options[] = "hvc:d:t:";
21+
static const char options[] = "hvc:d:t:b:i:";
1922

2023
static const char detail_options[] = R"(
2124
-h Print help infomation
2225
-v Show verbose infomation
2326
-c <connections> Number of connections, default: 1000
2427
-d <duration> Duration of test, default: 10s
2528
-t <threads> Number of threads, default: 4
29+
-b <bytes> Content-Length, default: 0
30+
-i <interval> Interval of timer, default: 0ms
2631
)";
2732

2833
static int connections = 1000;
29-
static int duration = 10;
34+
static int duration = 10; // s
3035
static int threads = 4;
36+
static int bytes = 0; // byte
37+
static int interval = 0; // ms
3138

3239
static bool verbose = false;
3340
static const char* url = NULL;
@@ -48,6 +55,8 @@ typedef struct connection_s {
4855
uint64_t response_cnt;
4956
uint64_t ok_cnt;
5057
uint64_t readbytes;
58+
uint64_t start_time;
59+
std::vector<int> delays;
5160

5261
connection_s()
5362
: parser(HttpParser::New(HTTP_CLIENT, HTTP_V1))
@@ -63,6 +72,7 @@ typedef struct connection_s {
6372
}
6473

6574
void SendRequest() {
75+
start_time = hloop_now_ms(hevent_loop(io));
6676
hio_write(io, request_msg.data(), request_msg.size());
6777
++request_cnt;
6878
parser->InitResponse(response.get());
@@ -77,6 +87,8 @@ typedef struct connection_s {
7787
return false;
7888
}
7989
if (parser->IsComplete()) {
90+
int delay = hloop_now_ms(hevent_loop(io)) - start_time;
91+
delays.push_back(delay);
8092
++response_cnt;
8193
if (response->status_code == HTTP_STATUS_OK) {
8294
++ok_cnt;
@@ -90,6 +102,7 @@ static connection_t** conns = NULL;
90102

91103
static std::atomic<int> connected_num(0);
92104
static std::atomic<int> disconnected_num(0);
105+
static unsigned int connect_start_time = 0;
93106

94107
static void print_help() {
95108
printf("Usage: wrk [%s] <url>\n", options);
@@ -106,13 +119,20 @@ static void print_result() {
106119
uint64_t total_response_cnt = 0;
107120
uint64_t total_ok_cnt = 0;
108121
uint64_t total_readbytes = 0;
122+
uint64_t total_delay = 0;
123+
std::vector<int> delays;
109124
connection_t* conn = NULL;
110125
for (int i = 0; i < connections; ++i) {
111126
conn = conns[i];
112127
total_request_cnt += conn->request_cnt;
113128
total_response_cnt += conn->response_cnt;
114129
total_ok_cnt += conn->ok_cnt;
115130
total_readbytes += conn->readbytes;
131+
delays.insert(delays.end(), conn->delays.begin(), conn->delays.end());
132+
}
133+
std::sort(delays.begin(), delays.end());
134+
for (int i = 0; i < delays.size(); ++i) {
135+
total_delay += delays[i];
116136
}
117137
printf("%llu requests, %llu OK, %lluMB read in %ds\n",
118138
LLU(total_request_cnt),
@@ -121,6 +141,19 @@ static void print_result() {
121141
duration);
122142
printf("Requests/sec: %8llu\n", LLU(total_response_cnt / duration));
123143
printf("Transfer/sec: %8lluMB\n", LLU((total_readbytes / duration) >> 20));
144+
printf("Latency avg: %8llums\n", LLU(total_delay / delays.size()));
145+
printf("Percentage of the requests served within a certain time (ms)\n");
146+
printf(" 50%% %d\n", delays[delays.size() * 0.5]);
147+
printf(" 60%% %d\n", delays[delays.size() * 0.6]);
148+
printf(" 70%% %d\n", delays[delays.size() * 0.7]);
149+
printf(" 80%% %d\n", delays[delays.size() * 0.8]);
150+
printf(" 90%% %d\n", delays[delays.size() * 0.9]);
151+
printf(" 95%% %d\n", delays[delays.size() * 0.95]);
152+
printf(" 96%% %d\n", delays[delays.size() * 0.96]);
153+
printf(" 97%% %d\n", delays[delays.size() * 0.97]);
154+
printf(" 98%% %d\n", delays[delays.size() * 0.98]);
155+
printf(" 99%% %d\n", delays[delays.size() * 0.99]);
156+
printf(" 100%% %d (longest delay)\n", delays.back());
124157
}
125158

126159
static void start_reconnect(hio_t* io);
@@ -140,19 +173,30 @@ static void on_close(hio_t* io) {
140173
static void on_recv(hio_t* io, void* buf, int readbytes) {
141174
connection_t* conn = (connection_t*)hevent_userdata(io);
142175
if (conn->RecvResponse((const char*)buf, readbytes)) {
143-
conn->SendRequest();
176+
if (interval == 0) {
177+
conn->SendRequest();
178+
}
144179
}
145180
}
146181

182+
static void send_heartbeat(hio_t* io) {
183+
connection_t* conn = (connection_t*)hevent_userdata(io);
184+
conn->SendRequest();
185+
}
186+
147187
static void on_connect(hio_t* io) {
148188
if (++connected_num == connections) {
149189
if (verbose) {
150-
printf("all connected\n");
190+
printf("all connected in %ums\n", gettick_ms() - connect_start_time);
151191
}
152192
}
153193

154194
connection_t* conn = (connection_t*)hevent_userdata(io);
155-
conn->SendRequest();
195+
if (interval == 0) {
196+
conn->SendRequest();
197+
} else {
198+
hio_set_heartbeat(io, interval, send_heartbeat);
199+
}
156200

157201
hio_setcb_read(io, on_recv);
158202
hio_read(io);
@@ -203,10 +247,14 @@ int main(int argc, char** argv) {
203247
const char* strConnections = get_arg("c");
204248
const char* strDuration = get_arg("d");
205249
const char* strThreads = get_arg("t");
250+
const char* strBytes = get_arg("b");
251+
const char* strInterval = get_arg("i");
206252

207253
if (strConnections) connections = atoi(strConnections);
208254
if (strDuration) duration = atoi(strDuration);
209255
if (strThreads) threads = atoi(strThreads);
256+
if (strBytes) bytes = atoi(strBytes);
257+
if (strInterval) interval = atoi(strInterval);
210258

211259
print_cmd();
212260

@@ -243,14 +291,19 @@ int main(int argc, char** argv) {
243291
// Dump request
244292
request->headers["User-Agent"] = std::string("libhv/") + hv_version();
245293
request->headers["Connection"] = "keep-alive";
294+
if (bytes > 0) {
295+
request->method = HTTP_POST;
296+
request->body = std::string(bytes, 'a');
297+
}
246298
request_msg = request->Dump(true, true);
247-
printf("%s", request_msg.c_str());
299+
printf("%.*s", int(request_msg.size() - request->body.size()), request_msg.c_str());
248300

249301
// EventLoopThreadPool
250302
EventLoopThreadPool loop_threads(threads);
251303
loop_threads.start(true);
252304

253305
// connections
306+
connect_start_time = gettick_ms();
254307
conns = (connection_t**)malloc(sizeof(connection_t*) * connections);
255308
for (int i = 0; i < connections; ++i) {
256309
conns[i] = new connection_t;

0 commit comments

Comments
 (0)