RFR 8193832: Performance of InputStream.readAllBytes() could be improved

Paul Sandoz paul.sandoz at oracle.com
Thu Dec 21 19:44:07 UTC 2017



> On 21 Dec 2017, at 11:05, Brian Burkhalter <brian.burkhalter at oracle.com> wrote:
> 
> Hi Paul,
> 
> On Dec 21, 2017, at 10:28 AM, Paul Sandoz <paul.sandoz at oracle.com <mailto:paul.sandoz at oracle.com>> wrote:
> 
>> This looks ok, i think it’s definitely reached it’s complexity budget, and arguably over spent.
> 
> I concur that this horse is almost dead from the beatings but since I already hacked up Peter’s suggestion which eliminates intermediate copies I might as well hang it out there (see below).

That looks ok to me, i think keeping the buf allocation at the top of the loop tends to simplify the reasoning.


> 
>>>> 
>> I do have one follow on investigation we discussed off list that is worth measuring. At the end use the Unsafe array allocation with no zeroing, since the resulting array will be fully written into. This might result in an observable improvement.
> 
> I’ve not forgotten about that but do not know whether we want to include it as part of this issue or a subsequent one.
> 

I suggest a follow on investigation.

Paul.

> Thanks,
> 
> Brian
> 
>     public byte[] readAllBytes() throws IOException {
>         List<byte[]> bufs = null;
>         byte[] result = null;
>         int total = 0;
>         int n;
>         do {
>             byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
>             int nread = 0;
> 
>             // read to EOF which may read more or less than buffer size
>             while ((n = read(buf, nread, buf.length - nread)) > 0) {
>                 nread += n;
>             }
> 
>             if (nread > 0) {
>                 if (MAX_BUFFER_SIZE - total < nread) {
>                     throw new OutOfMemoryError("Required array size too large");
>                 }
>                 total += nread;
>                 if (result == null) {
>                     result = buf;
>                 } else {
>                     if (bufs == null) {
>                         bufs = new ArrayList<>();
>                         bufs.add(result);
>                     }
>                     bufs.add(buf);
>                 }
>             }
>         } while (n >= 0); // if the last call to read returned -1, then break
> 
>         if (bufs == null) {
>             if (result == null) {
>                 return new byte[0];
>             }
>             return result.length == total ?
>                 result : Arrays.copyOf(result, total);
>         }
> 
>         result = new byte[total];
>         int offset = 0;
>         int remaining = total;
>         for (byte[] b : bufs) {
>             int len = Math.min(b.length, remaining);
>             System.arraycopy(b, 0, result, offset, len);
>             offset += len;
>             remaining -= len;
>         }
> 
>         return result;
>     }



More information about the core-libs-dev mailing list