diff options
| author | Rob Pike <r@golang.org> | 2009-12-01 21:44:24 -0800 | 
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2009-12-01 21:44:24 -0800 | 
| commit | fe281ceb3e84bf3f8fee62b41ae2f177650ae00d (patch) | |
| tree | aeb74068d7c0ea3f3bc000f93e8e0e1c5d8a28dd | |
| parent | c0aa4181512776f35d60f61a7c64e6a37364332d (diff) | |
| download | golang-fe281ceb3e84bf3f8fee62b41ae2f177650ae00d.tar.gz | |
make io.ReadFile use Stat.Size as a hint for preallocation
R=rsc
CC=golang-dev
http://codereview.appspot.com/163069
| -rw-r--r-- | src/pkg/io/utils.go | 18 | 
1 files changed, 17 insertions, 1 deletions
| diff --git a/src/pkg/io/utils.go b/src/pkg/io/utils.go index ccd611571..0e0b84ae4 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. | 
