]> Cypherpunks repositories - gostls13.git/commitdiff
make io.ReadFile use Stat.Size as a hint for preallocation
authorRob Pike <r@golang.org>
Wed, 2 Dec 2009 05:44:24 +0000 (21:44 -0800)
committerRob Pike <r@golang.org>
Wed, 2 Dec 2009 05:44:24 +0000 (21:44 -0800)
R=rsc
CC=golang-dev
https://golang.org/cl/163069

src/pkg/io/utils.go

index ccd61157116a18ed46074cb76629c9e562fc65b2..0e0b84ae49e982285410584a25940d39712b9652 100644 (file)
@@ -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.