Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance is a bit strange #875

Open
xstar2091 opened this issue Aug 20, 2024 · 12 comments
Open

Performance is a bit strange #875

xstar2091 opened this issue Aug 20, 2024 · 12 comments
Labels
question Issue can be closed by providing information

Comments

@xstar2091
Copy link

xstar2091 commented Aug 20, 2024

I test Crow performance using the blowing code

#include <crow.h>

int main()
{
    crow::SimpleApp app;
    app.loglevel(crow::LogLevel::Warning);
    CROW_ROUTE(app, "/hello")
    ([]() {
        return "hello world";
    });
    app.port(18080)
      .multithreaded()
      .run();
    return 0;
}

Then run wrk
wrk -t12 -c400 -d30s http://127.0.0.1:18080/hello

The result shows

Running 30s test @ http://127.0.0.1:18080/hello
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.89ms    1.15ms  17.84ms   68.33%
    Req/Sec    17.55k     6.81k   42.22k    83.19%
  6298733 requests in 30.10s, 792.92MB read
Requests/sec: 209269.72
Transfer/sec:     26.34MB

I changed the code like blow

#include <crow.h>

int main()
{
    crow::SimpleApp app;
    app.loglevel(crow::LogLevel::Warning);
    CROW_ROUTE(app, "/hello")
    ([](const crow::request&, crow::response& res) {
        res.add_header("Content-Type", "plain/text");
        res.body = "hello world";
        res.end();
    });
    app.port(18080)
      .multithreaded()
      .run();
    return 0;
}

Then run the same wrk command
wrk -t12 -c400 -d30s http://127.0.0.1:18080/hello

The result shows
Running 30s test @ http://127.0.0.1:18080/hello
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    41.24ms    2.19ms  43.96ms   99.72%
    Req/Sec   802.78     85.53     1.20k    66.75%
  287830 requests in 30.04s, 43.42MB read
Requests/sec:   9581.56
Transfer/sec:      1.45MB

Why is there such a big difference in performance?

@gittiver gittiver added the question Issue can be closed by providing information label Aug 25, 2024
@gittiver
Copy link
Member

gittiver commented Aug 25, 2024

There could be two reasons - assigning the strings or res.end().
Could you check with
CROW_ROUTE(app, "/hello")
([](const crow::request&) {
crow::response res;
res.add_header("Content-Type", "plain/text");
res.body = "hello world";
return res;
});

@dr3mro
Copy link

dr3mro commented Aug 26, 2024

Why res.end() is so expensive?

@gittiver
Copy link
Member

I don't know, if it is. Did you test it?

@dr3mro
Copy link

dr3mro commented Aug 26, 2024 via email

@xstar2091
Copy link
Author

There could be two reasons - assigning the strings or res.end(). Could you check with CROW_ROUTE(app, "/hello") ([](const crow::request&) { crow::response res; res.add_header("Content-Type", "plain/text"); res.body = "hello world"; return res; });

I test the following two codes:

CROW_ROUTE(app, "/hello")
([](const crow::request&) {
    crow::response res;
    res.add_header("Content-Type", "plain/text");
    res.body = "hello world";
    return res;
});

and

CROW_ROUTE(app, "/hello")
([](const crow::request&) {
    crow::json::wvalue x({{"zmessage", "Hello, World!"},
                          {"amessage", "Hello, World2!"}});
    return x;
});

The Request/Sec is just 9580

Running 30s test @ http://127.0.0.1:18080/hello
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    41.24ms    2.16ms  43.05ms   99.72%
    Req/Sec   802.88     79.81     1.29k    70.67%
  287816 requests in 30.04s, 57.42MB read
Requests/sec:   9580.85
Transfer/sec:      1.91MB

I have no idea about the test result.

@xstar2091
Copy link
Author

There could be two reasons - assigning the strings or res.end(). Could you check with CROW_ROUTE(app, "/hello") ([](const crow::request&) { crow::response res; res.add_header("Content-Type", "plain/text"); res.body = "hello world"; return res; });

I did another test, use code

CROW_ROUTE(app, "/hello")
([](const crow::request&) {
    return "hello world";
});

The Requests/sec is 337253.80, the cpu usage is 485%
Use code

  CROW_ROUTE(app, "/hello")
    ([](const crow::request&) {
        crow::response res;
        res.add_header("Content-Type", "plain/text");
        res.body = "hello world";
        return res;
    });

The Requests/sec is 9586.31, the cpu usage is 25%

Is there some locks to block?

@gittiver
Copy link
Member

For me, it looks like res.add_header(...) let the handler run much longer.
That's even true for the json object created and returned.
Could you repeat with

CROW_ROUTE(app, "/hello")
    ([](const crow::request&) {
        crow::response res;
        res.body = "hello world";
        return res;
    });

Just to get sure for the function.

@gittiver
Copy link
Member

btw. what is the used hardware? In the logs should be visible how many concurrent accesses are possible.

@xstar2091
Copy link
Author

For me, it looks like res.add_header(...) let the handler run much longer. That's even true for the json object created and returned. Could you repeat with

CROW_ROUTE(app, "/hello")
    ([](const crow::request&) {
        crow::response res;
        res.body = "hello world";
        return res;
    });

Just to get sure for the function.

That is. I test this code, and the Requests/sec is 334266.41.
As http protocol, not setting a header is not a good idea, right?

@xstar2091
Copy link
Author

btw. what is the used hardware? In the logs should be visible how many concurrent accesses are possible.

I've set the logging level to Warning for the purpose of stress testing. The test results should have nothing to do with the hardware, I think.

@gittiver
Copy link
Member

self_t& multithreaded()
{
return concurrency(std::thread::hardware_concurrency());
}

multithreaded is using the hardware_concurrency level, thats why I am asking.

@xstar2091
Copy link
Author

btw. what is the used hardware? In the logs should be visible how many concurrent accesses are possible.

I have 8 concurrency threads. 11th Gen Intel® Core™ i7-1165G7 × 8, 40GiB RAM, Ubuntu 24.04

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issue can be closed by providing information
Projects
None yet
Development

No branches or pull requests

3 participants