C ++ std :: stringstream操作优化

时间:2017-12-30 01:14:20

标签: c++ optimization stringstream

我的情况如下:

  1. 我有一个二进制文件,我正在读取std :: fstream读取操作为(char *)
  2. 我的目标是从文件中取出每个字节,格式化十六进制,然后将其附加到字符串变量
  3. 字符串变量应保存按项目2格式化的文件的全部内容。
  4. 例如,假设我有以下二进制文件内容:

    D0 46 98 57 A0 24 99 56 A3

    我格式化每个字节的方式如下:

    stringstream fin;;
    
    for (size_t i = 0; i < fileb_size; ++i)
    {
    fin << hex << setfill('0') << setw(2) << static_cast<uint16_t>(fileb[i]);
    }
    
    // this would yield the output "D0469857A0249956A3"
    
    return fin.str();
    

    上面的方法按预期工作,然而,对于大文件来说,它是非常慢的,我理解; stringstream用于输入格式化!

    我的问题是,有没有办法优化这些代码或我一起采取的方法?我唯一的限制是输出应该是字符串格式,如上所示。

    谢谢。

1 个答案:

答案 0 :(得分:3)

std::stringstream相当慢。它不会预先分配,它总是涉及复制字符串,至少一次以检索它。转换为十六进制也可以手动编码更快。

我觉得这样的事情可能更有效:

// Quick and dirty
char to_hex(unsigned char nibble)
{
    assert(nibble < 16);

    if(nibble < 10)
        return char('0' + nibble);

    return char('A' + nibble - 10);
}

std::string to_hex(std::string const& filename)
{
    // open file at end
    std::ifstream ifs(filename, std::ios::binary|std::ios::ate);

    // calculate file size and move to beginning
    auto end = ifs.tellg();
    ifs.seekg(0, std::ios::beg);
    auto beg = ifs.tellg();

    // preallocate the string
    std::string out;
    out.reserve((end - beg) * 2);

    char buf[2048]; // larger = faster (within limits)

    while(ifs.read(buf, sizeof(buf)) || ifs.gcount())
    {
        for(std::streamsize i = 0; i < ifs.gcount(); ++i)
        {
            out += to_hex(static_cast<unsigned char>(buf[i]) >> 4); // top nibble
            out += to_hex(static_cast<unsigned char>(buf[i]) & 0b1111); // bottom nibble
        }
    }

    return out;
}

它附加到预先分配的字符串以最小化复制并避免重新分配。