Skip to content

Commit

Permalink
wrk show latency
Browse files Browse the repository at this point in the history
  • Loading branch information
ithewei committed Feb 7, 2025
1 parent 771ab9c commit 4f05ec3
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions examples/wrk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*
*/

#include <vector>
#include <algorithm>

#include "hv.h"
#include "hmain.h" // import parse_opt
#include "hloop.h"
Expand All @@ -15,19 +18,23 @@
#include "HttpParser.h"
using namespace hv;

static const char options[] = "hvc:d:t:";
static const char options[] = "hvc:d:t:b:i:";

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

static int connections = 1000;
static int duration = 10;
static int duration = 10; // s
static int threads = 4;
static int bytes = 0; // byte
static int interval = 0; // ms

static bool verbose = false;
static const char* url = NULL;
Expand All @@ -48,6 +55,8 @@ typedef struct connection_s {
uint64_t response_cnt;
uint64_t ok_cnt;
uint64_t readbytes;
uint64_t start_time;
std::vector<int> delays;

connection_s()
: parser(HttpParser::New(HTTP_CLIENT, HTTP_V1))
Expand All @@ -63,6 +72,7 @@ typedef struct connection_s {
}

void SendRequest() {
start_time = hloop_now_ms(hevent_loop(io));
hio_write(io, request_msg.data(), request_msg.size());
++request_cnt;
parser->InitResponse(response.get());
Expand All @@ -77,6 +87,8 @@ typedef struct connection_s {
return false;
}
if (parser->IsComplete()) {
int delay = hloop_now_ms(hevent_loop(io)) - start_time;
delays.push_back(delay);
++response_cnt;
if (response->status_code == HTTP_STATUS_OK) {
++ok_cnt;
Expand All @@ -90,6 +102,7 @@ static connection_t** conns = NULL;

static std::atomic<int> connected_num(0);
static std::atomic<int> disconnected_num(0);
static unsigned int connect_start_time = 0;

static void print_help() {
printf("Usage: wrk [%s] <url>\n", options);
Expand All @@ -106,13 +119,20 @@ static void print_result() {
uint64_t total_response_cnt = 0;
uint64_t total_ok_cnt = 0;
uint64_t total_readbytes = 0;
uint64_t total_delay = 0;
std::vector<int> delays;
connection_t* conn = NULL;
for (int i = 0; i < connections; ++i) {
conn = conns[i];
total_request_cnt += conn->request_cnt;
total_response_cnt += conn->response_cnt;
total_ok_cnt += conn->ok_cnt;
total_readbytes += conn->readbytes;
delays.insert(delays.end(), conn->delays.begin(), conn->delays.end());
}
std::sort(delays.begin(), delays.end());
for (int i = 0; i < delays.size(); ++i) {
total_delay += delays[i];
}
printf("%llu requests, %llu OK, %lluMB read in %ds\n",
LLU(total_request_cnt),
Expand All @@ -121,6 +141,19 @@ static void print_result() {
duration);
printf("Requests/sec: %8llu\n", LLU(total_response_cnt / duration));
printf("Transfer/sec: %8lluMB\n", LLU((total_readbytes / duration) >> 20));
printf("Latency avg: %8llums\n", LLU(total_delay / delays.size()));
printf("Percentage of the requests served within a certain time (ms)\n");
printf(" 50%% %d\n", delays[delays.size() * 0.5]);
printf(" 60%% %d\n", delays[delays.size() * 0.6]);
printf(" 70%% %d\n", delays[delays.size() * 0.7]);
printf(" 80%% %d\n", delays[delays.size() * 0.8]);
printf(" 90%% %d\n", delays[delays.size() * 0.9]);
printf(" 95%% %d\n", delays[delays.size() * 0.95]);
printf(" 96%% %d\n", delays[delays.size() * 0.96]);
printf(" 97%% %d\n", delays[delays.size() * 0.97]);
printf(" 98%% %d\n", delays[delays.size() * 0.98]);
printf(" 99%% %d\n", delays[delays.size() * 0.99]);
printf(" 100%% %d (longest delay)\n", delays.back());
}

static void start_reconnect(hio_t* io);
Expand All @@ -140,19 +173,30 @@ static void on_close(hio_t* io) {
static void on_recv(hio_t* io, void* buf, int readbytes) {
connection_t* conn = (connection_t*)hevent_userdata(io);
if (conn->RecvResponse((const char*)buf, readbytes)) {
conn->SendRequest();
if (interval == 0) {
conn->SendRequest();
}
}
}

static void send_heartbeat(hio_t* io) {
connection_t* conn = (connection_t*)hevent_userdata(io);
conn->SendRequest();
}

static void on_connect(hio_t* io) {
if (++connected_num == connections) {
if (verbose) {
printf("all connected\n");
printf("all connected in %ums\n", gettick_ms() - connect_start_time);
}
}

connection_t* conn = (connection_t*)hevent_userdata(io);
conn->SendRequest();
if (interval == 0) {
conn->SendRequest();
} else {
hio_set_heartbeat(io, interval, send_heartbeat);
}

hio_setcb_read(io, on_recv);
hio_read(io);
Expand Down Expand Up @@ -203,10 +247,14 @@ int main(int argc, char** argv) {
const char* strConnections = get_arg("c");
const char* strDuration = get_arg("d");
const char* strThreads = get_arg("t");
const char* strBytes = get_arg("b");
const char* strInterval = get_arg("i");

if (strConnections) connections = atoi(strConnections);
if (strDuration) duration = atoi(strDuration);
if (strThreads) threads = atoi(strThreads);
if (strBytes) bytes = atoi(strBytes);
if (strInterval) interval = atoi(strInterval);

print_cmd();

Expand Down Expand Up @@ -243,14 +291,19 @@ int main(int argc, char** argv) {
// Dump request
request->headers["User-Agent"] = std::string("libhv/") + hv_version();
request->headers["Connection"] = "keep-alive";
if (bytes > 0) {
request->method = HTTP_POST;
request->body = std::string(bytes, 'a');
}
request_msg = request->Dump(true, true);
printf("%s", request_msg.c_str());
printf("%.*s", int(request_msg.size() - request->body.size()), request_msg.c_str());

// EventLoopThreadPool
EventLoopThreadPool loop_threads(threads);
loop_threads.start(true);

// connections
connect_start_time = gettick_ms();
conns = (connection_t**)malloc(sizeof(connection_t*) * connections);
for (int i = 0; i < connections; ++i) {
conns[i] = new connection_t;
Expand Down

0 comments on commit 4f05ec3

Please sign in to comment.