From 9b4f3eaf17e3200fe77a7b094abb6a7a5f7a854f Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Sun, 20 Mar 2022 16:49:32 +0800 Subject: [PATCH] dynsystem.SparseInputStream: Implement read(buf, off, len) InstallationAsyncTask calls SparseInputStream.read(buf, off, len), however SparseInputStream didn't override that method, so the method actually fallbacks to the default implementation, which is a for-loop calling read() (single byte). This is a significant performance hit. This modest fix boosts the DSU installation time significantly: * physical device: 45s -> 15s * virtual device: 30s -> 7s Bug: 225310919 Test: start a Dynamic System installation Change-Id: I5a61dc2e9554719aece43491b813f6647b4bcc65 --- .../android/dynsystem/SparseInputStream.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java index 4117d0f07e0f4..7d2326693a174 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java @@ -133,36 +133,32 @@ public class SparseInputStream extends InputStream { return mLeft == 0; } - /** - * It overrides the InputStream.read(byte[] buf) - */ - public int read(byte[] buf) throws IOException { + @Override + public int read(byte[] buf, int off, int len) throws IOException { if (!mIsSparse) { - return mIn.read(buf); + return mIn.read(buf, off, len); } if (prepareChunk()) return -1; int n = -1; switch (mCur.mChunkType) { case SparseChunk.RAW: - n = mIn.read(buf, 0, (int) min(mLeft, buf.length)); + n = mIn.read(buf, off, (int) min(mLeft, len)); mLeft -= n; return n; case SparseChunk.DONTCARE: - n = (int) min(mLeft, buf.length); - Arrays.fill(buf, 0, n - 1, (byte) 0); + n = (int) min(mLeft, len); + Arrays.fill(buf, off, off + n, (byte) 0); mLeft -= n; return n; case SparseChunk.FILL: // The FILL type is rarely used, so use a simple implmentation. - return super.read(buf); + return super.read(buf, off, len); default: throw new IOException("Unsupported Chunk:" + mCur.toString()); } } - /** - * It overrides the InputStream.read() - */ + @Override public int read() throws IOException { if (!mIsSparse) { return mIn.read();