[libcxx-commits] [libcxx] [libc++] Optimize ofstream::write (PR #123337)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 17 05:30:33 PST 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/123337
```
----------------------------
Benchmark old new
----------------------------
bm_write 1382 ns 521 ns
```
>From 502f8f2578c19820af71f639ac156528da9b8988 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 17 Jan 2025 13:26:38 +0100
Subject: [PATCH] [libc++] Optimize ofstream::write
---
libcxx/docs/ReleaseNotes/20.rst | 3 +++
libcxx/include/fstream | 12 +++++++++
.../benchmarks/streams/ofstream.bench.cpp | 25 +++++++++++++++++++
3 files changed, 40 insertions(+)
create mode 100644 libcxx/test/benchmarks/streams/ofstream.bench.cpp
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index 2736061544c531..50ab4aad48c24f 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -111,6 +111,9 @@ Improvements and New Features
std::errc::not_a_directory``, or use ``err.default_error_condition()`` to map to an ``error_condition``, and then test
its ``value()`` and ``category()``.
+- ``ofstream::write`` has been optimized to pass through large strings to system calls directly instead of copying them
+ in chunks into a buffer.
+
Deprecations and Removals
-------------------------
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index f0e9425e0a53d9..61cf396a661822 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -232,6 +232,8 @@ _LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) no
template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
+ using __base = basic_streambuf<_CharT, _Traits>;
+
public:
typedef _CharT char_type;
typedef _Traits traits_type;
@@ -304,6 +306,16 @@ protected:
int sync() override;
void imbue(const locale& __loc) override;
+ _LIBCPP_HIDE_FROM_ABI streamsize xsputn(const char_type* __str, streamsize __len) override {
+ if (__always_noconv_ && __len >= (this->epptr() - this->pbase())) {
+ if (traits_type::eq_int_type(overflow(), traits_type::eof()))
+ return 0;
+
+ return std::fwrite(__str, sizeof(char_type), __len, __file_);
+ }
+ return __base::xsputn(__str, __len);
+ }
+
private:
char* __extbuf_;
const char* __extbufnext_;
diff --git a/libcxx/test/benchmarks/streams/ofstream.bench.cpp b/libcxx/test/benchmarks/streams/ofstream.bench.cpp
new file mode 100644
index 00000000000000..60606a9d67e2f5
--- /dev/null
+++ b/libcxx/test/benchmarks/streams/ofstream.bench.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <fstream>
+#include <vector>
+
+#include <benchmark/benchmark.h>
+
+static void bm_write(benchmark::State& state) {
+ std::vector<char> buffer;
+ buffer.resize(16384);
+
+ std::ofstream stream("/dev/null");
+
+ for (auto _ : state)
+ stream.write(buffer.data(), buffer.size());
+}
+BENCHMARK(bm_write);
+
+BENCHMARK_MAIN();
More information about the libcxx-commits
mailing list