1 /* 2 * Copyright (C) 2017 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.common.io; 16 17 import com.google.caliper.BeforeExperiment; 18 import com.google.caliper.Benchmark; 19 import com.google.caliper.Param; 20 import com.google.caliper.api.VmOptions; 21 import java.io.IOException; 22 import java.io.StringReader; 23 import java.io.StringWriter; 24 import java.nio.CharBuffer; 25 import java.util.Random; 26 27 /** 28 * Benchmarks for {@link CharStreams#copy}. 29 * 30 * <p>{@link CharStreams#copy} has type specific optimizations for various common Appendable and 31 * Reader implementations, this compares the performance of the different options. 32 */ 33 // These benchmarks allocate a lot of data so use a large heap 34 @VmOptions({"-Xms12g", "-Xmx12g", "-d64"}) 35 public class CharStreamsCopyBenchmark { 36 enum CopyStrategy { 37 OLD { 38 @Override copy(Readable from, Appendable to)39 long copy(Readable from, Appendable to) throws IOException { 40 CharBuffer buf = CharStreams.createBuffer(); 41 long total = 0; 42 while (from.read(buf) != -1) { 43 buf.flip(); 44 to.append(buf); 45 total += buf.remaining(); 46 buf.clear(); 47 } 48 return total; 49 } 50 }, 51 NEW { 52 @Override copy(Readable from, Appendable to)53 long copy(Readable from, Appendable to) throws IOException { 54 return CharStreams.copy(from, to); 55 } 56 }; 57 copy(Readable from, Appendable to)58 abstract long copy(Readable from, Appendable to) throws IOException; 59 } 60 61 enum TargetSupplier { 62 STRING_WRITER { 63 @Override get(int sz)64 Appendable get(int sz) { 65 return new StringWriter(sz); 66 } 67 }, 68 STRING_BUILDER { 69 @Override get(int sz)70 Appendable get(int sz) { 71 return new StringBuilder(sz); 72 } 73 }; 74 get(int sz)75 abstract Appendable get(int sz); 76 } 77 78 @Param CopyStrategy strategy; 79 @Param TargetSupplier target; 80 81 @Param({"10", "1024", "1048576"}) 82 int size; 83 84 String data; 85 86 @BeforeExperiment setUp()87 public void setUp() { 88 // precalculate some random strings of ascii characters. 89 StringBuilder sb = new StringBuilder(); 90 Random random = new Random(0xdeadbeef); // for unpredictable but reproducible behavior 91 sb.ensureCapacity(size); 92 for (int k = 0; k < size; k++) { 93 // [9-127) includes all ascii non-control characters 94 sb.append((char) (random.nextInt(127 - 9) + 9)); 95 } 96 data = sb.toString(); 97 } 98 99 @Benchmark timeCopy(int reps)100 public long timeCopy(int reps) throws IOException { 101 long r = 0; 102 final String localData = data; 103 final TargetSupplier localTarget = target; 104 final CopyStrategy localStrategy = strategy; 105 for (int i = 0; i < reps; i++) { 106 Appendable appendable = localTarget.get(localData.length()); 107 r += localStrategy.copy(new StringReader(localData), appendable); 108 } 109 return r; 110 } 111 } 112