drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.04k stars 1.06k forks source link

A way to use pJson.asCString() in template model #2034

Closed JonathanSF98 closed 1 month ago

JonathanSF98 commented 1 month ago

In this version, pJson.asCString() returns a pointer to the string data, and strlen is used to measure the length of the string without creating a temporary std::string object. It could be an alternative to improve how it was working previously. I hope it is useful.

Mis1eader-dev commented 1 month ago

Thank you for the contribution, however, this PR has loads of other commits with it, you should rebase it on master and make sure your branch is only 1 commit ahead of our upstream master.

Regarding the optimization itself, there's a better way to do this with C++17 compatibility in mind:

Json::Value json = ...;
const char *begin, *end;
std::string_view someKey;
if(!json["some key"].getString(&begin, &end) || (someKey = std::string_view(begin, end - begin)).size() < someLength)
    return ...;

// do something on someKey

This is a zero copy and prevents redundant operations.

Edit: if the value of the json isn't used, then:

Json::Value json = ...;
const char *begin, *end;
if(!json["some key"].getString(&begin, &end) || (end - begin) < someLength)
    return ...;

// do something on success or continue
JonathanSF98 commented 1 month ago

Thank you for the contribution, however, this PR has loads of other commits with it, you should rebase it on master and make sure your branch is only 1 commit ahead of our upstream master.

Regarding the optimization itself, there's a better way to do this with C++17 compatibility in mind:

Json::Value json = ...;
const char *begin, *end;
std::string_view someKey;
if(!json["some key"].getString(&begin, &end) || (someKey = std::string_view(begin, end - begin)).size() < someLength)
    return ...;

// do something on someKey

This is a zero copy and prevents redundant operations.

Edit: if the value of the json isn't used, then:

Json::Value json = ...;
const char *begin, *end;
if(!json["some key"].getString(&begin, &end) || (end - begin) < someLength)
    return ...;

// do something on success or continue

Branch fixed. Thank you for your feedback!

One reason I suggested this more direct solution is because it's compatible across different versions of C++ and it uses the pure implementation of a const char*. However, your solution undoubtedly offers better performance for those utilizing C++17 and beyond.

I even contemplated employing macros to accommodate other versions of C++, but I weighed the potential increase in complexity that could ensue. Also, this is my first time constributing for Drogon, I aimed not to be overly very intrusive xD