简体   繁体   中英

ReadFile std::unique_ptr vs. std::vector vs. std::string

Which one of the following would be the most efficient and why? I'm leaning towards the unique_ptr because I think that there is no copy being done when returning the data read. It's just a transfer of ownership of a pointer.

For example, I think that the string version would create a temporary string, read data into that, and upon returning, it'd copy its data into the assigned result?

However, I'm not sure that I'm right. Any ideas what I mean and which is the best?

UniquePtr:

std::unique_ptr<const char[]> ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);

    if (file.is_open())
    {
        file.seekg(0, std::ios::end);
        std::size_t size = file.tellg();
        std::unique_ptr<char[]> result(new char[size]);
        file.seekg(0, std::ios::beg);
        file.read(result.get(), size);
        file.close();
        return std::move(result);
    }
    return nullptr;
}

Vector:

std::string ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);

    if (file.is_open())
    {
        file.seekg(0, std::ios::end);
        std::vector<std::int8_t> buffer(file.tellg());
        file.seekg(0, std::ios::beg);
        file.read(result.data(), result.size());
        file.close();
        return std::string(result.data());
    }
    return std::string();
}

String:

std::string ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);

    if (file.is_open())
    {
        std::string result = std::string();
        file.seekg(0, std::ios::end);
        result.resize(file.tellg());
        file.seekg(0, std::ios::beg);
        file.read(&result[0], result.size());
        file.close();
        return result;
    }
    return std::string();
}
std::string ReadFile(const char* FileName)
{
    std::fstream file(FileName, std::ios::in);
    std::string result = std::string();

    if (file.is_open())
    {
        file.seekg(0, std::ios::end);
        result.resize(file.tellg());
        file.seekg(0, std::ios::beg);
        file.read(&result[0], result.size());
        file.close();
    }
    return result;
}

I have no proof , but if function has only one return , copy elision might be implemented by compiler , if there are 2 returns inside function , copy elision might not work as expected ~~~

The

 return std::string(result.data());

will only work if the data is null-terminated.

Apart from that complication it needlessly copies from a vector to a string.

The std::string code is most natural for reading text (text mode open of file).

You won't see much of a performance difference since the file i/o dwarfs the rest, but anyway with C++03 you will most likely get Return Value Optimization (depends on compiler), and with C++11 you will get move optimization of the result if you just use std::move .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM