From 2e5be2a7495ac0b204454c74664e590a38d039d3 Mon Sep 17 00:00:00 2001
From: Guillaume Bouchard <guillaume.bouchard@tweag.io>
Date: Wed, 29 Apr 2020 18:44:01 +0200
Subject: [PATCH] StringSink pre allocate

When used with `readFile`, we have a pretty good heuristic of the file
size, so `reserve` this in the `string`. This will save some allocation
/ copy when the string is growing.
---
 src/libutil/util.cc | 10 +++++++---
 src/libutil/util.hh |  2 +-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index bb4af747b..71db92d77 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -312,7 +312,11 @@ unsigned char getFileType(const Path & path)
 
 string readFile(int fd)
 {
-    return drainFD(fd, true);
+    struct stat st;
+    if (fstat(fd, &st) == -1)
+        throw SysError("statting file");
+
+    return drainFD(fd, true, st.st_size);
 }
 
 
@@ -658,9 +662,9 @@ void writeFull(int fd, const string & s, bool allowInterrupts)
 }
 
 
-string drainFD(int fd, bool block)
+string drainFD(int fd, bool block, const size_t reserveSize)
 {
-    StringSink sink;
+    StringSink sink(reserveSize);
     drainFD(fd, sink, block);
     return std::move(*sink.s);
 }
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 32ef9a79a..1b263abcc 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -162,7 +162,7 @@ MakeError(EndOfFile, Error);
 
 
 /* Read a file descriptor until EOF occurs. */
-string drainFD(int fd, bool block = true);
+string drainFD(int fd, bool block = true, const size_t reserveSize=0);
 
 void drainFD(int fd, Sink & sink, bool block = true);
 
-- 
GitLab