1 // Licensed to the Apache Software Foundation(ASF) under one 2 // or more contributor license agreements.See the NOTICE file 3 // distributed with this work for additional information 4 // regarding copyright ownership.The ASF licenses this file 5 // to you under the Apache License, Version 2.0 (the 6 // "License"); you may not use this file except in compliance 7 // with the License. You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 using System; 19 using System.Collections.Generic; 20 using System.Text; 21 using ThriftTest; 22 using Thrift.Collections; 23 using Thrift.Protocol; 24 using System.Threading; 25 using Thrift.Transport.Client; 26 using System.Threading.Tasks; 27 using System.Diagnostics; 28 using Thrift.Transport; 29 30 namespace Client.Tests 31 { 32 public class PerformanceTests 33 { 34 private CancellationTokenSource Cancel; 35 private CrazyNesting Testdata; 36 private TMemoryBufferTransport MemBuffer; 37 private TTransport Transport; 38 private LayeredChoice Layered; 39 Execute()40 internal static int Execute() 41 { 42 var instance = new PerformanceTests(); 43 instance.ProtocolPeformanceTestAsync().Wait(); 44 45 // debug only 46 if (Debugger.IsAttached) 47 { 48 Console.Write("Hit ENTER ..."); 49 Console.ReadKey(); 50 } 51 52 return 0; 53 } 54 ProtocolPeformanceTestAsync()55 private async Task ProtocolPeformanceTestAsync() 56 { 57 Console.WriteLine("Setting up for ProtocolPeformanceTestAsync ..."); 58 Cancel = new CancellationTokenSource(); 59 Testdata = TestDataFactory.CreateCrazyNesting(); 60 61 foreach (var layered in Enum.GetValues(typeof(LayeredChoice))) 62 { 63 Layered = (LayeredChoice)layered; 64 65 await RunTestAsync(async (bool b) => { return await GenericProtocolFactory<TBinaryProtocol>(b); }); 66 await RunTestAsync(async (bool b) => { return await GenericProtocolFactory<TCompactProtocol>(b); }); 67 //await RunTestAsync(async (bool b) => { return await GenericProtocolFactory<TJsonProtocol>(b); }); 68 } 69 } 70 71 private Task<TProtocol> GenericProtocolFactory<T>(bool forWrite) 72 where T : TProtocol 73 { 74 var oldTrans = Transport; 75 try 76 { 77 // read happens after write here, so let's take over the written bytes 78 if (forWrite) 79 MemBuffer = new TMemoryBufferTransport(); 80 else 81 MemBuffer = new TMemoryBufferTransport(MemBuffer.GetBuffer()); 82 83 // layered transports anyone? 84 switch (Layered) 85 { 86 case LayeredChoice.None: 87 Transport = MemBuffer; 88 break; 89 case LayeredChoice.Framed: 90 Transport = new TFramedTransport(MemBuffer); 91 break; 92 case LayeredChoice.Buffered: 93 Transport = new TBufferedTransport(MemBuffer); 94 break; 95 default: 96 Debug.Assert(false); 97 break; 98 } 99 100 if (!Transport.IsOpen) 101 Transport.OpenAsync().Wait(); 102 103 var instance = (T)Activator.CreateInstance(typeof(T), Transport); 104 return Task.FromResult<TProtocol>(instance); 105 } 106 finally 107 { 108 if (oldTrans is IDisposable) 109 (oldTrans as IDisposable).Dispose(); 110 } 111 } 112 GetProtocolTransportName(TProtocol proto)113 private string GetProtocolTransportName(TProtocol proto) 114 { 115 var name = Transport.GetType().Name; 116 if (name.Equals(MemBuffer.GetType().Name)) 117 name = string.Empty; 118 else 119 name = " + " + name; 120 121 name = proto.GetType().Name + name; 122 return name; 123 } 124 125 RunTestAsync(Func<bool, Task<TProtocol>> factory)126 private async Task RunTestAsync(Func<bool, Task<TProtocol>> factory) 127 { 128 var stop = new Stopwatch(); 129 130 var proto = await factory(true); 131 stop.Start(); 132 await Testdata.WriteAsync(proto, Cancel.Token); 133 await Transport.FlushAsync(Cancel.Token); 134 stop.Stop(); 135 Console.WriteLine("RunTestAsync({0}): write = {1} msec", 136 GetProtocolTransportName(proto), 137 stop.ElapsedMilliseconds); 138 139 var restored = new CrazyNesting(); 140 proto = await factory(false); 141 stop.Start(); 142 await restored.ReadAsync(proto, Cancel.Token); 143 stop.Stop(); 144 Console.WriteLine("RunTestAsync({0}): read = {1} msec", 145 GetProtocolTransportName(proto), 146 stop.ElapsedMilliseconds); 147 } 148 149 } 150 } 151