Check-in [701ac713de]
Overview
SHA1:701ac713deb812f7f5feda484c6a43147071f8f9
Date: 2014-12-24 23:33:45
User: spaskalev
Comment:Made SizedReader faster by keeping explicit buffer indices.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2014-12-24
23:45
[b703c38e0b] Extracted SizedReader to a sizedReader type with a Read() method. Closures seem to be slower in Go 1.4 and there is no real need for SizedReader to be a closure. (user: spaskalev, tags: trunk)
23:33
[701ac713de] Made SizedReader faster by keeping explicit buffer indices. (user: spaskalev, tags: trunk)
22:32
[1717bfae3b] Use 0dev.org/ioutil.SizedWriter as an output buffer for pdc in both compress and decompress modes. (user: spaskalev, tags: trunk)
Changes

Modified src/0dev.org/ioutil/ioutil.go from [bca057263b] to [e5419d451e].

    82     82   	return write
    83     83   }
    84     84   
    85     85   // Returns a reader that delegates calls to Read(...) while ensuring
    86     86   // that the output buffer is never smaller than the required size
    87     87   // and is downsized to a multiple of the required size if larger.
    88     88   func SizedReader(reader io.Reader, size int) io.Reader {
    89         -	var buffer []byte = make([]byte, 0, size)
           89  +	var (
           90  +		buffer   []byte = make([]byte, size)
           91  +		from, to int    = 0, 0
           92  +	)
    90     93   
    91     94   	return ReaderFunc(func(output []byte) (int, error) {
    92     95   		var (
    93     96   			count int
    94     97   			err   error
    95     98   		)
           99  +
    96    100   	start:
    97    101   		// Reply with the buffered data if there is any
    98         -		if len(buffer) > 0 {
    99         -			count = copy(output, buffer)
          102  +		if to-from > 0 {
          103  +			count = copy(output, buffer[from:to])
   100    104   
   101    105   			// Advance the data in the buffer
   102         -			buffer = buffer[:copy(buffer, buffer[count:])]
          106  +			from += count
   103    107   
   104         -			// Return count and error if we have read the whole buffer
   105         -			if len(buffer) == 0 {
          108  +			// Check whether we have reached the end of the buffer
          109  +			if to-from == 0 {
          110  +				// Reset the buffer
          111  +				from, to = 0, 0
          112  +
   106    113   				return count, err
   107    114   			}
   108    115   
   109    116   			// Do not propagate an error until the buffer is exhausted
   110    117   			return count, nil
   111    118   		}
   112    119   
   113    120   		// Delegate if the buffer is empty and the destination buffer is large enough
   114    121   		if len(output) >= size {
   115    122   			return reader.Read(output[:(len(output)/size)*size])
   116    123   		}
   117    124   
   118    125   		// Perform a read into the buffer
   119         -		count, err = reader.Read(buffer[:size])
          126  +		count, err = reader.Read(buffer)
   120    127   
   121    128   		// Size the buffer down to the read data size
   122    129   		// and restart if we have successfully read some bytes
   123         -		buffer = buffer[:count]
   124         -		if len(buffer) > 0 {
          130  +		from, to = 0, count
          131  +		if to-from > 0 {
   125    132   			goto start
   126    133   		}
   127    134   
   128    135   		// Returning on err/misbehaving noop reader
   129    136   		return 0, err
   130    137   	})
   131    138   }