无符号数据类型的MSVCifstream性能问题

std::ifstream在读取二进制文件时,我在 MSVC 上做了一些测试。我在charunsigned char数据类型之间有很大的性能差异。

读取 512 MB 二进制文件时的结果:

Duration read as signed: 322 ms
Duration read as unsigned: 10552 ms
Duration read as signed: 322 ms
Duration read as unsigned: 10552 ms

在我用来测试的代码下面:

我不明白使用 abasic_ifstream<unsigned char>basic_ifstream<char>读取二进制文件时慢 30 倍。

回答

我已将其跟踪到C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.29.30037includefstream文件第 549 行:

virtual streamsize __CLR_OR_THIS_CALL xsgetn(_Elem* _Ptr, streamsize _Count) override {
    // get _Count characters from stream
    if constexpr (sizeof(_Elem) == 1) {
        if (_Count <= 0) {
            return 0;
        }

        if (_Pcvt) { // if we need a nontrivial codecvt transform, do the default expensive thing
            return _Mysb::xsgetn(_Ptr, _Count);
        }

因为unsigned char它进入那个default expensive thing

再看远一点,我看到了这个:

virtual streamsize __CLR_OR_THIS_CALL xsgetn(_Elem* _Ptr, streamsize _Count) { // get _Count characters from stream
    const streamsize _Start_count = _Count;

    while (0 < _Count) {
        streamsize _Size = _Gnavail();
        if (0 < _Size) { // copy from read buffer
            if (_Count < _Size) {
                _Size = _Count;
            }

            _Traits::copy(_Ptr, gptr(), static_cast<size_t>(_Size));
            _Ptr += _Size;
            _Count -= _Size;
            gbump(static_cast<int>(_Size));
        } else {
            const int_type _Meta = uflow();
            if (_Traits::eq_int_type(_Traits::eof(), _Meta)) {
                break; // end of file, quit
            }

            // get a single character
            *_Ptr++ = _Traits::to_char_type(_Meta);
            --_Count;
        }
    }

    return _Start_count - _Count;
}

注意一一处理!而这个功能并没有做太多:

_NODISCARD static constexpr _Elem to_char_type(const int_type& _Meta) noexcept {
    return static_cast<_Elem>(_Meta);
}


以上是无符号数据类型的MSVCifstream性能问题的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>