在一个程序中,我正在以下列方式处理一些用于字节的别名:
#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版本也无法运行,这与我之前所写的相反。
答案 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
。