Search code examples
c++performancec++14copy-elisionreturn-value-optimization

c++14 return a value by reference to optimize performance


I have a method that ultimately will take a value from an internal api call

auto val = api->post(req);  //step 1

// the post returns a class of "type json"

json api::post(const request& request) { //step 2

   // do some job
   json j = << some json data>>
   return j;

}

Now there is a third step that prepares the http response back to the external caller.

response server::http_response(const json &final_jsond) {

    auto response = response{final_json}; //that makes the json a string for the http payload
    response.set_header("Content-Type", "application/json");

    return response;
}

Now, this code works, however I am wondering if I am missing some modern C++ principles in order to avoid copying the json object from one call to another

Can the above code be optimized by using modern c++ methods to become faster?

returning by reference maybe?


Solution

  • As others have suggested, the return should be OK as written. If it's reasonable for server::http_response to consume its argument and if response actually holds onto a json or onto data in it, then you could do

    response server::http_response(json&& final_json) {
        auto response = response{std::move(final_json)}; //that makes the json a string for the http payload
        response.set_header("Content-Type", "application/json");
    
        return response; // You don't need std::move here.
    }
    

    I use this pattern sometimes when copying is expensive. It forces the caller to do myResponse = myServer.http_response(std::move(final_json));, which is desirable for performance. If the caller wants to keep their json object, then they can instead call myServer.http_response(json(final_json));. Put another way, if http_response takes an rvalue reference, then the caller can provide it either by std::moveing or by constructing an unnamed temporary. But then the inefficiency of copying is on the caller.

    PS

    Have you measured this to be a performance bottleneck?

    PPS

    Having response be a type name and a variable name is a questionable choice.