A
A
Arkady Baganin2021-06-24 22:20:41
C++ / C#
Arkady Baganin, 2021-06-24 22:20:41

How to optimize the CPU load when sending a message?

Hey toast ;) I got a "small" problem when sending the slice file as JSON. I am writing a kind of FTP server with JSON in c ++ (I use the library from nlohmann) .

The essence of the problem: When sending a JSON message with a file, there is a very large CPU load (9-14%, for comparison, Discord eats 2% with the demo enabled, the browser has 1-2%) ...

The code of this great code

void TcpCommander::ADownload(std::string args, SOCKET client) {
  json r;

  std::vector<std::uint8_t> package_data;
  std::basic_ifstream<std::uint8_t> package_download;

  std::string req = std::string("download ");
  req.append(args);

  try {
    package_download.open(args.c_str(), std::ifstream::binary);

    if (package_download.good() && package_download.is_open()) {
      package_download.seekg(0, ifstream::end);

      unsigned int length = (unsigned int)package_download.tellg();
      package_download.seekg(0, ifstream::beg);

      unsigned int pkg_count = length / PKG_SIZE;
      unsigned int lpkg_size = length % PKG_SIZE;

      if (lpkg_size < 1 && length <= PKG_SIZE)
        lpkg_size = length;

      if (pkg_count < 1 && lpkg_size > 0) {
        package_download.read(&package_data[0], lpkg_size * sizeof(std::uint8_t));

        r["result"] = {
          {"req", req},
          {"code", 0},
          {"pkg", {
            {"id", pkg_count},
            {"count", pkg_count},
            {"size", lpkg_size},
            {"buffer", json::binary_t(package_data)}
          }}
        };

        this->SendCommand(client, r.dump());

        r.clear();

        package_data.clear();
        package_data.shrink_to_fit();
      }
      else if (lpkg_size > 0) {
        for (unsigned int i = 0; i < pkg_count; i++) {
          unsigned int pkg_id = i + 1;
          unsigned int pkg_size = 0;

          if (pkg_id < pkg_count) {
            pkg_size = PKG_SIZE;
          }
          else if (lpkg_size > 0) {
            pkg_size = lpkg_size;
          }

          package_data.resize((size_t)pkg_size * sizeof(unsigned char));
          package_download.read(&package_data[0], pkg_size * sizeof(std::uint8_t));

          r["result"] = {
            {"req", req},
            {"code", 0},
            {"pkg", {
              {"id", pkg_id},
              {"count", pkg_count},
              {"size", pkg_size},
              {"buffer", json::binary_t(package_data)}
            }}
          };

          if (!this->SendCommand(client, r.dump()))
            i = pkg_count;

          r.clear();

          package_data.clear();
          package_data.shrink_to_fit();

          std::this_thread::sleep_for(std::chrono::milliseconds(DOWNLOAD_DELAY));
        }
      }

      r.clear();

      package_data.clear();
      package_data.shrink_to_fit();

      package_download.close();
    }
    else {
      package_download.close();

      r["result"] = {
        {"req", req},
        {"code", GetLastError()}
      };
    }
  }
  catch (exception ex) {
    json j_ex;

    j_ex["result"] = {
      {"req", ex.what()},
      {"code", GetLastError()}
    };

    this->SendCommand(client, j_ex.dump());

    j_ex.clear();
  }
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
none7, 2021-06-25
@ark_yt

Indeed, why is it so slow? Maybe because binary_t produces something similar?
{"bytes":[116,101,115,116],"subtype":null}.
That is, EVERY byte is converted to a decimal number. Even with the use of a slightly accelerated algorithm, this all takes a lot of processor time.

A
Alexander Ananiev, 2021-06-24
@SaNNy32

You can optimize the load by fixing the section of the source code that gives the maximum load. You can identify such a section of code using a profiler.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question