> On 21 Dec 2017, at 11:05, Brian Burkhalter <brian.burkhal...@oracle.com> > wrote: > > Hi Paul, > > On Dec 21, 2017, at 10:28 AM, Paul Sandoz <paul.san...@oracle.com > <mailto:paul.san...@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; > }