From f9810f1b12750e83d3b76f703b9956e390ee06e7 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 1 Dec 2009 21:44:24 -0800 Subject: [PATCH] make io.ReadFile use Stat.Size as a hint for preallocation R=rsc CC=golang-dev https://golang.org/cl/163069 --- src/pkg/io/utils.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/pkg/io/utils.go b/src/pkg/io/utils.go index ccd6115711..0e0b84ae49 100644 --- a/src/pkg/io/utils.go +++ b/src/pkg/io/utils.go @@ -26,7 +26,23 @@ func ReadFile(filename string) ([]byte, os.Error) { return nil, err } defer f.Close(); - return ReadAll(f); + // It's a good but not certain bet that Stat will tell us exactly how much to + // read, so let's try it but be prepared for the answer to be wrong. + dir, err := f.Stat(); + var n uint64; + if err != nil && dir.Size < 2e9 { // Don't preallocate a huge buffer, just in case. + n = dir.Size + } + if n == 0 { + n = 1024 // No idea what's right, but zero isn't. + } + // Pre-allocate the correct size of buffer, then set its size to zero. The + // Buffer will read into the allocated space cheaply. If the size was wrong, + // we'll either waste some space off the end or reallocate as needed, but + // in the overwhelmingly common case we'll get it just right. + buf := bytes.NewBuffer(make([]byte, n)[0:0]); + _, err = Copy(buf, f); + return buf.Bytes(), err; } // WriteFile writes data to a file named by filename. -- 2.50.0