Skip to content

Commit acf6825

Browse files
committed
[libc++] Optimize fstream::read
1 parent 63b83ea commit acf6825

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ Improvements and New Features
6464
by up to 2.5x
6565
- The performance of ``erase(iterator, iterator)`` in the unordered containers has been improved by up to 1.9x
6666
- The performance of ``map::insert_or_assign`` has been improved by up to 2x
67-
- ``ofstream::write`` has been optimized to pass through large strings to system calls directly instead of copying them
68-
in chunks into a buffer.
67+
- ``ofstream::write`` and ``ifstream::read`` have been optimized to pass through large reads and writes to system calls
68+
directly instead of copying them in chunks.
6969
- Multiple internal types have been refactored to use ``[[no_unique_address]]``, resulting in faster compile times and
7070
reduced debug information.
7171

libcxx/include/fstream

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,19 @@ protected:
308308
return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len);
309309
}
310310

311+
_LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsgetn(char_type* __str, streamsize __len) override {
312+
if (__always_noconv_) {
313+
const streamsize __n = std::min(this->egptr() - this->gptr(), __len);
314+
if (__n != 0) {
315+
traits_type::copy(__str, this->gptr(), __n);
316+
this->__gbump_ptrdiff(__n);
317+
}
318+
if (__len - __n >= this->egptr() - this->eback())
319+
return std::fread(__str + __n, sizeof(char_type), __len - __n, __file_);
320+
}
321+
return basic_streambuf<_CharT, _Traits>::xsgetn(__str, __len);
322+
}
323+
311324
private:
312325
char* __extbuf_;
313326
const char* __extbufnext_;

libcxx/test/benchmarks/streams/ofstream.bench.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,22 @@ static void bm_write(benchmark::State& state) {
2222
}
2323
BENCHMARK(bm_write);
2424

25+
static void bm_read(benchmark::State& state) {
26+
std::vector<char> buffer;
27+
buffer.resize(16384);
28+
29+
std::ofstream gen_testfile("testfile");
30+
gen_testfile.write(buffer.data(), buffer.size());
31+
32+
std::ifstream stream("testfile");
33+
assert(stream);
34+
35+
for (auto _ : state) {
36+
stream.read(buffer.data(), buffer.size());
37+
benchmark::DoNotOptimize(buffer);
38+
stream.seekg(0);
39+
}
40+
}
41+
BENCHMARK(bm_read);
42+
2543
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)