1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.util;
18 
19 import android.perftests.utils.BenchmarkState;
20 import android.perftests.utils.PerfStatusReporter;
21 
22 import androidx.test.filters.LargeTest;
23 import androidx.test.runner.AndroidJUnit4;
24 
25 import com.android.modules.utils.FastDataInput;
26 import com.android.modules.utils.FastDataOutput;
27 
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 
32 import java.io.BufferedInputStream;
33 import java.io.BufferedOutputStream;
34 import java.io.ByteArrayInputStream;
35 import java.io.ByteArrayOutputStream;
36 import java.io.DataInput;
37 import java.io.DataInputStream;
38 import java.io.DataOutput;
39 import java.io.DataOutputStream;
40 import java.io.IOException;
41 
42 @LargeTest
43 @RunWith(AndroidJUnit4.class)
44 public class FastDataPerfTest {
45     @Rule
46     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
47 
48     private static final int OUTPUT_SIZE = 64000;
49     private static final int BUFFER_SIZE = 4096;
50 
51     @Test
timeWrite_Upstream()52     public void timeWrite_Upstream() throws IOException {
53         final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
54         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
55         while (state.keepRunning()) {
56             os.reset();
57             final BufferedOutputStream bos = new BufferedOutputStream(os, BUFFER_SIZE);
58             final DataOutputStream out = new DataOutputStream(bos);
59             try {
60                 doWrite(out);
61                 out.flush();
62             } finally {
63                 out.close();
64             }
65         }
66     }
67 
68     @Test
timeWrite_LocalUsing4ByteSequences()69     public void timeWrite_LocalUsing4ByteSequences() throws IOException {
70         final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
71         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
72         while (state.keepRunning()) {
73             os.reset();
74             final FastDataOutput out = ArtFastDataOutput.obtain(os);
75             try {
76                 doWrite(out);
77                 out.flush();
78             } finally {
79                 out.release();
80             }
81         }
82     }
83 
84     @Test
timeWrite_LocalUsing3ByteSequences()85     public void timeWrite_LocalUsing3ByteSequences() throws IOException {
86         final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
87         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
88         while (state.keepRunning()) {
89             os.reset();
90             final FastDataOutput out = FastDataOutput.obtain(os);
91             try {
92                 doWrite(out);
93                 out.flush();
94             } finally {
95                 out.release();
96             }
97         }
98     }
99 
100     @Test
timeRead_Upstream()101     public void timeRead_Upstream() throws Exception {
102         final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
103         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
104         while (state.keepRunning()) {
105             is.reset();
106             final BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE);
107             final DataInputStream in = new DataInputStream(bis);
108             try {
109                 doRead(in);
110             } finally {
111                 in.close();
112             }
113         }
114     }
115 
116     @Test
timeRead_LocalUsing4ByteSequences()117     public void timeRead_LocalUsing4ByteSequences() throws Exception {
118         final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
119         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
120         while (state.keepRunning()) {
121             is.reset();
122             final FastDataInput in = ArtFastDataInput.obtain(is);
123             try {
124                 doRead(in);
125             } finally {
126                 in.release();
127             }
128         }
129     }
130 
131     @Test
timeRead_LocalUsing3ByteSequences()132     public void timeRead_LocalUsing3ByteSequences() throws Exception {
133         final ByteArrayInputStream is = new ByteArrayInputStream(doWrite());
134         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
135         while (state.keepRunning()) {
136             is.reset();
137             final FastDataInput in = FastDataInput.obtain(is);
138             try {
139                 doRead(in);
140             } finally {
141                 in.release();
142             }
143         }
144     }
145 
146     /**
147      * Since each iteration is around 64 bytes, we need to iterate many times to
148      * exercise the buffer logic.
149      */
150     private static final int REPEATS = 1000;
151 
doWrite()152     private static byte[] doWrite() throws IOException {
153         final ByteArrayOutputStream os = new ByteArrayOutputStream(OUTPUT_SIZE);
154         final DataOutput out = new DataOutputStream(os);
155         doWrite(out);
156         return os.toByteArray();
157     }
158 
doWrite(DataOutput out)159     private static void doWrite(DataOutput out) throws IOException {
160         for (int i = 0; i < REPEATS; i++) {
161             out.writeByte(Byte.MAX_VALUE);
162             out.writeShort(Short.MAX_VALUE);
163             out.writeInt(Integer.MAX_VALUE);
164             out.writeLong(Long.MAX_VALUE);
165             out.writeFloat(Float.MAX_VALUE);
166             out.writeDouble(Double.MAX_VALUE);
167             out.writeUTF("com.example.typical_package_name");
168         }
169     }
170 
doRead(DataInput in)171     private static void doRead(DataInput in) throws IOException {
172         for (int i = 0; i < REPEATS; i++) {
173             in.readByte();
174             in.readShort();
175             in.readInt();
176             in.readLong();
177             in.readFloat();
178             in.readDouble();
179             in.readUTF();
180         }
181     }
182 }
183