为什么basic_fstream <unsigned char =“”>在Windows上比basic_fstream <char>慢几个数量级?

时间:2017-12-07 19:54:51

标签: c++ windows performance file io

在一个程序中,我正在以下列方式处理一些用于字节的别名:

#include <fstream>
#include <vector>
using Byte = unsigned char;

void write(const Byte* buffer, size_t size) {
    std::basic_fstream<Byte> file("1gb_file", std::ios::in | std::ios::out);
    file.write(buffer, size);
    file.flush(); // To ensure the data is being written, to eliminate caching claims
}

int main(){
    auto GB = 1024u * 1024u * 1024u;
    std::vector<Byte> zeros(GB, 0);
    write(zeros.data(), zeros.size());
    return 0;
}

此功能在Byte == unsigned char上执行的时间:在我的全新SSD上的52.0245s,在发布模式下为MSVC-x64。

另一方面,如果我们将定义更改为Byte == char:1.46725s。就是这样。

为什么会出现这种差异,是否有使用标准库来避免此类陷阱的一般良好做法?

注意(由于错误而编辑):在Linux上,当给出unsigned char(在gcc和clang上)时,代码实际上无法运行,正如@SergeyA指出的那样。 Windows上的GCC版本也无法运行,这与我之前所写的相反。

1 个答案:

答案 0 :(得分:-1)

我要在这里咬紧牙关,并猜测它与语言环境有关。基于我所拥有的非常有限的信息,它看起来像在MSVC unsigned char流中执行区域设置转换,而普通的char流不会,而只是执行批量IO。 (见关于http://en.cppreference.com/w/cpp/io/basic_ostream/write的说明)。

有趣的是,相同的代码片段在我使用g ++ 5.4的Linux安装上根本不起作用(相当古老,我知道)。写入失败是由于流类中的某个内部成员为nullptr(无论谁感兴趣的是_M_codecvt),并且设置了流badbit