c++ 使用clang-tidy获取看似无用的“性能低效字符串连接”警告

vbopmzt1  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(137)

在我的C++应用程序中,我使用+操作符连接几个字符串,如下所示:

#include <string>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <sstream>

std::string download_file_contents(const std::string& server_url)
{
    const curlpp::options::Url url(server_url);
    curlpp::Easy request;
    request.setOpt(url);

    std::ostringstream output_stream;
    const curlpp::options::WriteStream write_stream(&output_stream);
    request.setOpt(write_stream);
    request.perform();

    return output_stream.str();
}

const std::string server_files_url = "https://example.com";

int main()
{
    for (const std::map<std::string, std::string> files = { {"a", "b" }, { "c", "d" }};
        const auto& [key, value] : files)
    {
        try
        {
            const auto file_download_url = server_files_url + "/?" + key; // Warning occurs here at "+ key"
            const auto file_contents = download_file_contents(file_download_url);
            std::cout << key << " downloaded, value: " << value << std::endl;
        }
        catch (const std::exception& exception)
        {
            std::cerr << "Exception: " << exception.what() << std::endl;
        }
    }
}

字符串连接代码在for循环中调用。使用string.append()在这里似乎没有意义,因为我需要为例如创建一个新的变量。每次迭代的file_download_url:修改server_files_url在语义上是不正确的。为什么我仍然收到clang警告performance-inefficient-string-concatenation?在每次循环迭代的单行代码中使用两次+运算符,我并没有真正的性能问题。我还相信MSVC编译器会足够聪明,在发布模式下尽可能地优化字符串连接,以避免任何潜在的性能影响。我猜clang-tidy并不关心潜在的编译器优化是否执行。
有什么想法,如何正确地重写这段代码来避免警告吗?

i2byvkas

i2byvkas1#

好吧,看起来使用std::ostringstream可以避免创建不必要的字符串:

#include <string>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <sstream>

std::string download_file_contents(const std::string& server_url)
{
    const curlpp::options::Url url(server_url);
    curlpp::Easy request;
    request.setOpt(url);

    std::ostringstream output_stream;
    const curlpp::options::WriteStream write_stream(&output_stream);
    request.setOpt(write_stream);
    request.perform();

    return output_stream.str();
}

const std::string server_files_url = "https://example.com";

int main()
{
    for (const std::map<std::string, std::string> files = { {"a", "b" }, { "c", "d" }};
        const auto& [key, value] : files)
    {
        try
        {
            std::ostringstream file_download_url_stream;
            file_download_url_stream << server_files_url << "/?" << key;
            const auto file_download_url = file_download_url_stream.str();
            
            const auto file_contents = download_file_contents(file_download_url);
            std::cout << key << " downloaded, value: " << value << std::endl;
        }
        catch (const std::exception& exception)
        {
            std::cerr << "Exception: " << exception.what() << std::endl;
        }
    }
}

相关问题