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.Buffer; 25 import java.nio.CharBuffer; 26 import java.util.Random; 27 28 /** 29 * Benchmarks for {@link CharStreams#copy}. 30 * 31 * <p>{@link CharStreams#copy} has type specific optimizations for various common Appendable and 32 * Reader implementations, this compares the performance of the different options. 33 */ 34 // These benchmarks allocate a lot of data so use a large heap 35 @VmOptions({"-Xms12g", "-Xmx12g", "-d64"}) 36 public class CharStreamsCopyBenchmark { 37 enum CopyStrategy { 38 OLD { 39 @Override copy(Readable from, Appendable to)40 long copy(Readable from, Appendable to) throws IOException { 41 CharBuffer buf = CharStreams.createBuffer(); 42 long total = 0; 43 while (from.read(buf) != -1) { 44 ((Buffer) buf).flip(); 45 to.append(buf); 46 total += buf.remaining(); 47 ((Buffer) buf).clear(); 48 } 49 return total; 50 } 51 }, 52 NEW { 53 @Override copy(Readable from, Appendable to)54 long copy(Readable from, Appendable to) throws IOException { 55 return CharStreams.copy(from, to); 56 } 57 }; 58 copy(Readable from, Appendable to)59 abstract long copy(Readable from, Appendable to) throws IOException; 60 } 61 62 enum TargetSupplier { 63 STRING_WRITER { 64 @Override get(int sz)65 Appendable get(int sz) { 66 return new StringWriter(sz); 67 } 68 }, 69 STRING_BUILDER { 70 @Override get(int sz)71 Appendable get(int sz) { 72 return new StringBuilder(sz); 73 } 74 }; 75 get(int sz)76 abstract Appendable get(int sz); 77 } 78 79 @Param CopyStrategy strategy; 80 @Param TargetSupplier target; 81 82 @Param({"10", "1024", "1048576"}) 83 int size; 84 85 String data; 86 87 @BeforeExperiment setUp()88 public void setUp() { 89 // precalculate some random strings of ascii characters. 90 StringBuilder sb = new StringBuilder(); 91 Random random = new Random(0xdeadbeef); // for unpredictable but reproducible behavior 92 sb.ensureCapacity(size); 93 for (int k = 0; k < size; k++) { 94 // [9-127) includes all ascii non-control characters 95 sb.append((char) (random.nextInt(127 - 9) + 9)); 96 } 97 data = sb.toString(); 98 } 99 100 @Benchmark timeCopy(int reps)101 public long timeCopy(int reps) throws IOException { 102 long r = 0; 103 final String localData = data; 104 final TargetSupplier localTarget = target; 105 final CopyStrategy localStrategy = strategy; 106 for (int i = 0; i < reps; i++) { 107 Appendable appendable = localTarget.get(localData.length()); 108 r += localStrategy.copy(new StringReader(localData), appendable); 109 } 110 return r; 111 } 112 } 113