1 2 package com.google.protobuf; 3 4 import com.google.caliper.BeforeExperiment; 5 import com.google.caliper.AfterExperiment; 6 import com.google.caliper.Benchmark; 7 import com.google.caliper.Param; 8 import com.google.caliper.api.VmOptions; 9 import com.google.protobuf.ByteString; 10 import com.google.protobuf.CodedOutputStream; 11 import com.google.protobuf.ExtensionRegistry; 12 import com.google.protobuf.Message; 13 import com.google.protobuf.benchmarks.Benchmarks.BenchmarkDataset; 14 import java.io.ByteArrayInputStream; 15 import java.io.ByteArrayOutputStream; 16 import java.io.BufferedWriter; 17 import java.io.File; 18 import java.io.FileNotFoundException; 19 import java.io.FileOutputStream; 20 import java.io.FileWriter; 21 import java.io.IOException; 22 import java.io.RandomAccessFile; 23 import java.util.ArrayList; 24 import java.util.List; 25 26 // Caliper set CICompilerCount to 1 for making sure compilation doesn't run in parallel with itself, 27 // This makes TieredCompilation not working. We just disable TieredCompilation by default. In master 28 // branch this has been disabled by default in caliper: 29 // https://github.com/google/caliper/blob/master/caliper-runner/src/main/java/com/google/caliper/runner/target/Jvm.java#L38:14 30 // But this haven't been added into most recent release. 31 @VmOptions("-XX:-TieredCompilation") 32 public class ProtoCaliperBenchmark { 33 public enum BenchmarkMessageType { 34 GOOGLE_MESSAGE1_PROTO3 { getExtensionRegistry()35 @Override ExtensionRegistry getExtensionRegistry() { return ExtensionRegistry.newInstance(); } 36 @Override getDefaultInstance()37 Message getDefaultInstance() { 38 return com.google.protobuf.benchmarks.BenchmarkMessage1Proto3.GoogleMessage1 39 .getDefaultInstance(); 40 } 41 }, 42 GOOGLE_MESSAGE1_PROTO2 { getExtensionRegistry()43 @Override ExtensionRegistry getExtensionRegistry() { return ExtensionRegistry.newInstance(); } 44 @Override getDefaultInstance()45 Message getDefaultInstance() { 46 return com.google.protobuf.benchmarks.BenchmarkMessage1Proto2.GoogleMessage1 47 .getDefaultInstance(); 48 } 49 }, 50 GOOGLE_MESSAGE2 { getExtensionRegistry()51 @Override ExtensionRegistry getExtensionRegistry() { return ExtensionRegistry.newInstance(); } 52 @Override getDefaultInstance()53 Message getDefaultInstance() { 54 return com.google.protobuf.benchmarks.BenchmarkMessage2.GoogleMessage2.getDefaultInstance(); 55 } 56 }, 57 GOOGLE_MESSAGE3 { 58 @Override getExtensionRegistry()59 ExtensionRegistry getExtensionRegistry() { 60 ExtensionRegistry extensions = ExtensionRegistry.newInstance(); 61 com.google.protobuf.benchmarks.BenchmarkMessage38.registerAllExtensions(extensions); 62 com.google.protobuf.benchmarks.BenchmarkMessage37.registerAllExtensions(extensions); 63 com.google.protobuf.benchmarks.BenchmarkMessage36.registerAllExtensions(extensions); 64 com.google.protobuf.benchmarks.BenchmarkMessage35.registerAllExtensions(extensions); 65 com.google.protobuf.benchmarks.BenchmarkMessage34.registerAllExtensions(extensions); 66 com.google.protobuf.benchmarks.BenchmarkMessage33.registerAllExtensions(extensions); 67 com.google.protobuf.benchmarks.BenchmarkMessage32.registerAllExtensions(extensions); 68 com.google.protobuf.benchmarks.BenchmarkMessage31.registerAllExtensions(extensions); 69 com.google.protobuf.benchmarks.BenchmarkMessage3.registerAllExtensions(extensions); 70 return extensions; 71 } 72 @Override getDefaultInstance()73 Message getDefaultInstance() { 74 return com.google.protobuf.benchmarks.BenchmarkMessage3.GoogleMessage3.getDefaultInstance(); 75 } 76 }, 77 GOOGLE_MESSAGE4 { 78 @Override getExtensionRegistry()79 ExtensionRegistry getExtensionRegistry() { 80 ExtensionRegistry extensions = ExtensionRegistry.newInstance(); 81 com.google.protobuf.benchmarks.BenchmarkMessage43.registerAllExtensions(extensions); 82 com.google.protobuf.benchmarks.BenchmarkMessage42.registerAllExtensions(extensions); 83 com.google.protobuf.benchmarks.BenchmarkMessage41.registerAllExtensions(extensions); 84 com.google.protobuf.benchmarks.BenchmarkMessage4.registerAllExtensions(extensions); 85 return extensions; 86 } 87 @Override getDefaultInstance()88 Message getDefaultInstance() { 89 return com.google.protobuf.benchmarks.BenchmarkMessage4.GoogleMessage4.getDefaultInstance(); 90 } 91 }; 92 getExtensionRegistry()93 abstract ExtensionRegistry getExtensionRegistry(); getDefaultInstance()94 abstract Message getDefaultInstance(); 95 } 96 97 private BenchmarkMessageType benchmarkMessageType; 98 @Param("") 99 private String dataFile; 100 101 private byte[] inputData; 102 private BenchmarkDataset benchmarkDataset; 103 private Message defaultMessage; 104 private ExtensionRegistry extensions; 105 private List<byte[]> inputDataList; 106 private List<ByteArrayInputStream> inputStreamList; 107 private List<ByteString> inputStringList; 108 private List<Message> sampleMessageList; 109 getMessageType()110 private BenchmarkMessageType getMessageType() throws IOException { 111 if (benchmarkDataset.getMessageName().equals("benchmarks.proto3.GoogleMessage1")) { 112 return BenchmarkMessageType.GOOGLE_MESSAGE1_PROTO3; 113 } else if (benchmarkDataset.getMessageName().equals("benchmarks.proto2.GoogleMessage1")) { 114 return BenchmarkMessageType.GOOGLE_MESSAGE1_PROTO2; 115 } else if (benchmarkDataset.getMessageName().equals("benchmarks.proto2.GoogleMessage2")) { 116 return BenchmarkMessageType.GOOGLE_MESSAGE2; 117 } else if (benchmarkDataset.getMessageName(). 118 equals("benchmarks.google_message3.GoogleMessage3")) { 119 return BenchmarkMessageType.GOOGLE_MESSAGE3; 120 } else if (benchmarkDataset.getMessageName(). 121 equals("benchmarks.google_message4.GoogleMessage4")) { 122 return BenchmarkMessageType.GOOGLE_MESSAGE4; 123 } else { 124 throw new IllegalStateException("Invalid DataFile! There's no testing message named " 125 + benchmarkDataset.getMessageName()); 126 } 127 } 128 129 @BeforeExperiment setUp()130 void setUp() throws IOException { 131 if (!dataFile.equals("")) { 132 RandomAccessFile file = new RandomAccessFile(new File(dataFile), "r"); 133 inputData = new byte[(int) file.length()]; 134 file.readFully(inputData); 135 benchmarkDataset = BenchmarkDataset.parseFrom(inputData); 136 benchmarkMessageType = getMessageType(); 137 } else { 138 inputData = new byte[0]; 139 benchmarkDataset = BenchmarkDataset.parseFrom(inputData); 140 benchmarkMessageType = BenchmarkMessageType.GOOGLE_MESSAGE2; 141 } 142 defaultMessage = benchmarkMessageType.getDefaultInstance(); 143 extensions = benchmarkMessageType.getExtensionRegistry(); 144 inputDataList = new ArrayList<byte[]>(); 145 inputStreamList = new ArrayList<ByteArrayInputStream>(); 146 inputStringList = new ArrayList<ByteString>(); 147 sampleMessageList = new ArrayList<Message>(); 148 149 for (int i = 0; i < benchmarkDataset.getPayloadCount(); i++) { 150 byte[] singleInputData = benchmarkDataset.getPayload(i).toByteArray(); 151 inputDataList.add(benchmarkDataset.getPayload(i).toByteArray()); 152 inputStreamList.add(new ByteArrayInputStream( 153 benchmarkDataset.getPayload(i).toByteArray())); 154 inputStringList.add(benchmarkDataset.getPayload(i)); 155 sampleMessageList.add( 156 defaultMessage.newBuilderForType().mergeFrom(singleInputData, extensions).build()); 157 } 158 } 159 160 161 @Benchmark serializeToByteArray(int reps)162 void serializeToByteArray(int reps) throws IOException { 163 if (sampleMessageList.size() == 0) { 164 return; 165 } 166 for (int i = 0; i < reps; i++) { 167 for (int j = 0; j < sampleMessageList.size(); j++) { 168 sampleMessageList.get(j).toByteArray(); 169 } 170 } 171 } 172 173 @Benchmark serializeToMemoryStream(int reps)174 void serializeToMemoryStream(int reps) throws IOException { 175 if (sampleMessageList.size() == 0) { 176 return; 177 } 178 for (int i = 0; i < reps; i++) { 179 for (int j = 0; j < sampleMessageList.size(); j++) { 180 ByteArrayOutputStream output = new ByteArrayOutputStream(); 181 sampleMessageList.get(j).writeTo(output); 182 } 183 } 184 } 185 186 @Benchmark deserializeFromByteArray(int reps)187 void deserializeFromByteArray(int reps) throws IOException { 188 if (inputDataList.size() == 0) { 189 return; 190 } 191 for (int i = 0; i < reps; i++) { 192 for (int j = 0; j < inputDataList.size(); j++) { 193 benchmarkMessageType.getDefaultInstance().getParserForType().parseFrom( 194 inputDataList.get(j), extensions); 195 } 196 } 197 } 198 199 @Benchmark deserializeFromMemoryStream(int reps)200 void deserializeFromMemoryStream(int reps) throws IOException { 201 if (inputStreamList.size() == 0) { 202 return; 203 } 204 for (int i = 0; i < reps; i++) { 205 for (int j = 0; j < inputStreamList.size(); j++) { 206 benchmarkMessageType.getDefaultInstance().getParserForType().parseFrom( 207 inputStreamList.get(j), extensions); 208 inputStreamList.get(j).reset(); 209 } 210 } 211 } 212 } 213 214 215