Skip to content

Commit 502f8f2

Browse files
committed
[libc++] Optimize ofstream::write
1 parent e79bb87 commit 502f8f2

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

libcxx/docs/ReleaseNotes/20.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ Improvements and New Features
111111
std::errc::not_a_directory``, or use ``err.default_error_condition()`` to map to an ``error_condition``, and then test
112112
its ``value()`` and ``category()``.
113113

114+
- ``ofstream::write`` has been optimized to pass through large strings to system calls directly instead of copying them
115+
in chunks into a buffer.
116+
114117
Deprecations and Removals
115118
-------------------------
116119

libcxx/include/fstream

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ _LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) no
232232

233233
template <class _CharT, class _Traits>
234234
class _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
235+
using __base = basic_streambuf<_CharT, _Traits>;
236+
235237
public:
236238
typedef _CharT char_type;
237239
typedef _Traits traits_type;
@@ -304,6 +306,16 @@ protected:
304306
int sync() override;
305307
void imbue(const locale& __loc) override;
306308

309+
_LIBCPP_HIDE_FROM_ABI streamsize xsputn(const char_type* __str, streamsize __len) override {
310+
if (__always_noconv_ && __len >= (this->epptr() - this->pbase())) {
311+
if (traits_type::eq_int_type(overflow(), traits_type::eof()))
312+
return 0;
313+
314+
return std::fwrite(__str, sizeof(char_type), __len, __file_);
315+
}
316+
return __base::xsputn(__str, __len);
317+
}
318+
307319
private:
308320
char* __extbuf_;
309321
const char* __extbufnext_;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <fstream>
10+
#include <vector>
11+
12+
#include <benchmark/benchmark.h>
13+
14+
static void bm_write(benchmark::State& state) {
15+
std::vector<char> buffer;
16+
buffer.resize(16384);
17+
18+
std::ofstream stream("/dev/null");
19+
20+
for (auto _ : state)
21+
stream.write(buffer.data(), buffer.size());
22+
}
23+
BENCHMARK(bm_write);
24+
25+
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)