-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance Tuning of std::filebuf #2481
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -211,6 +211,9 @@ public: | |
|
||
void swap(basic_filebuf& _Right) { | ||
if (this != _STD addressof(_Right)) { | ||
auto _Binary_sav = _Binary; | ||
_Binary = _Right._Binary; | ||
_Right._Binary = _Binary_sav; | ||
FILE* _Myfile_sav = _Myfile; | ||
const _Cvt* _Pcvt_sav = _Pcvt; | ||
typename _Traits::state_type _State_sav = _State; | ||
|
@@ -281,6 +284,7 @@ public: | |
} | ||
|
||
basic_filebuf* open(const char* _Filename, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { | ||
this->_Binary = _Mode & ios::binary; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use |
||
// _Prot is an extension | ||
if (_Myfile) { | ||
return nullptr; | ||
|
@@ -308,6 +312,7 @@ public: | |
#endif // _HAS_OLD_IOSTREAMS_MEMBERS | ||
|
||
basic_filebuf* open(const wchar_t* _Filename, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { | ||
this->_Binary = _Mode & ios::binary; | ||
// in standard as const std::filesystem::path::value_type *; _Prot is an extension | ||
if (_Myfile) { | ||
return nullptr; | ||
|
@@ -356,6 +361,7 @@ public: | |
#ifdef _NATIVE_WCHAR_T_DEFINED | ||
basic_filebuf* open( | ||
const unsigned short* _Filename, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { | ||
this->_Binary = _Mode & ios::binary; | ||
// in standard as const std::filesystem::path::value_type *; _Prot is an extension | ||
if (_Myfile) { | ||
return nullptr; | ||
|
@@ -583,15 +589,21 @@ protected: | |
|
||
if (_Myfile) { // open C stream, attempt read | ||
_Reset_back(); // revert from _Mychar buffer | ||
// process in 4k - 1 chunks to avoid tripping over fread's clobber-the-end behavior when | ||
// doing \r\n -> \n translation | ||
constexpr size_t _Read_size = 4095; // _INTERNAL_BUFSIZ - 1 | ||
while (_Read_size < _Count_s) { | ||
const auto _Actual_read = _CSTD fread(_Ptr, sizeof(_Elem), _Read_size, _Myfile); | ||
_Ptr += _Actual_read; | ||
_Count_s -= _Actual_read; | ||
if (_Actual_read != _Read_size) { | ||
return static_cast<streamsize>(_Start_count - _Count_s); | ||
|
||
if (!_Binary) { | ||
// binary mode does not require a \r\n -> \n translation | ||
// fread only 4095 bytes at a time may result in low performance when reading large files | ||
|
||
// process in 4k - 1 chunks to avoid tripping over fread's clobber-the-end behavior when | ||
// doing \r\n -> \n translation | ||
constexpr size_t _Read_size = 4095; // _INTERNAL_BUFSIZ - 1 | ||
while (_Read_size < _Count_s) { | ||
const auto _Actual_read = _CSTD fread(_Ptr, sizeof(_Elem), _Read_size, _Myfile); | ||
_Ptr += _Actual_read; | ||
_Count_s -= _Actual_read; | ||
if (_Actual_read != _Read_size) { | ||
return static_cast<streamsize>(_Start_count - _Count_s); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -781,6 +793,7 @@ private: | |
typename _Traits::state_type _State; // current conversion state | ||
bool _Closef; // true if C stream must be closed | ||
FILE* _Myfile; // pointer to C stream | ||
bool _Binary;// true if open with ios::binary | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this addition breaks ABI compatibility, so can only be done in ABI-breaking vNext release. Should the compatibility be broken here, could be a good thing to reorder members to put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for reviewing and your valuable advices.If I fix the ABI compatibility breaking,would it be accepted soon? ^_^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a maintainer. I'm also not sure if you can do the same without ABI break. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry... But the std::filebuf‘s low perf is more serious than I described. Some low level api or code may be useful for doing the same without ABI break .But it may also fail of course. I'm trying. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AlexGuteniev is correct - adding a data member to Unfortunately, at this time there is no ETA for the "vNext" ABI-breaking release. 😿 (The maintainers would love to break ABI and fix a whole bunch of bugs, but we need to coordinate with the compiler front-end team, and they were too overloaded with high-priority tasks at the beginning of the VS 2022 release cycle.) If there's no way to update this PR to improve performance while strictly preserving bincompat, we'll need to close it and instead file a tracking issue labeled There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did find a way to fix it without breaking binary compatibility,but it's not available in stl for the time being.
But it needs locating "__pioinfo" which is not exported in ms c runtime. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks - yeah, unfortunately reaching into UCRT internals is something that the STL avoids (although the VC Libraries team co-maintains the UCRT along with the Windows team, we consider the UCRT and STL to be separate libraries that shouldn't access internal data structure representations). We talked about this at the weekly maintainer meeting - I've filed #2490 to track this work for vNext (there's no ETA but it's not happening in the near future, so we'd prefer to track this with an issue instead of keeping a PR open for a year or more). I'll go ahead and close this now. |
||
|
||
void _Reset_back() { // restore buffer after putback | ||
if (_Mysb::eback() == &_Mychar) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use clang-format