summaryrefslogtreecommitdiff
path: root/test/netstd
diff options
context:
space:
mode:
authorJens Geyer <jensg@apache.org>2019-05-26 15:53:37 +0200
committerJens Geyer <jensg@apache.org>2019-06-04 22:31:58 +0200
commit5a17b13ebcba71181498ac3ccfa1e8aa04018a72 (patch)
tree946389a1dfee45e8401aaafa62d20a9f745e3a4d /test/netstd
parent057bebc1c346d6adcc2894d8f299c4276650d33d (diff)
downloadthrift-5a17b13ebcba71181498ac3ccfa1e8aa04018a72.tar.gz
THRIFT-4879 general performance improvements for netstd library
Client: netstd Patch: Jens Geyer This closes #1808
Diffstat (limited to 'test/netstd')
-rw-r--r--test/netstd/Client/Performance/PerformanceTests.cs150
-rw-r--r--test/netstd/Client/Performance/TestDataFactory.cs154
-rw-r--r--test/netstd/Client/Program.cs5
3 files changed, 308 insertions, 1 deletions
diff --git a/test/netstd/Client/Performance/PerformanceTests.cs b/test/netstd/Client/Performance/PerformanceTests.cs
new file mode 100644
index 000000000..041d12eae
--- /dev/null
+++ b/test/netstd/Client/Performance/PerformanceTests.cs
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ThriftTest;
+using Thrift.Collections;
+using Thrift.Protocol;
+using System.Threading;
+using Thrift.Transport.Client;
+using System.Threading.Tasks;
+using System.Diagnostics;
+using Thrift.Transport;
+
+namespace Client.Tests
+{
+ public class PerformanceTests
+ {
+ private CancellationTokenSource Cancel;
+ private CrazyNesting Testdata;
+ private TMemoryBufferTransport MemBuffer;
+ private TTransport Transport;
+ private LayeredChoice Layered;
+
+ internal static int Execute()
+ {
+ var instance = new PerformanceTests();
+ instance.ProtocolPeformanceTestAsync().Wait();
+
+ // debug only
+ if (Debugger.IsAttached)
+ {
+ Console.Write("Hit ENTER ...");
+ Console.ReadKey();
+ }
+
+ return 0;
+ }
+
+ private async Task ProtocolPeformanceTestAsync()
+ {
+ Console.WriteLine("Setting up for ProtocolPeformanceTestAsync ...");
+ Cancel = new CancellationTokenSource();
+ Testdata = TestDataFactory.CreateCrazyNesting();
+
+ foreach (var layered in Enum.GetValues(typeof(LayeredChoice)))
+ {
+ Layered = (LayeredChoice)layered;
+
+ await RunTestAsync(async (bool b) => { return await GenericProtocolFactory<TBinaryProtocol>(b); });
+ await RunTestAsync(async (bool b) => { return await GenericProtocolFactory<TCompactProtocol>(b); });
+ //await RunTestAsync(async (bool b) => { return await GenericProtocolFactory<TJsonProtocol>(b); });
+ }
+ }
+
+ private Task<TProtocol> GenericProtocolFactory<T>(bool forWrite)
+ where T : TProtocol
+ {
+ var oldTrans = Transport;
+ try
+ {
+ // read happens after write here, so let's take over the written bytes
+ if (forWrite)
+ MemBuffer = new TMemoryBufferTransport();
+ else
+ MemBuffer = new TMemoryBufferTransport(MemBuffer.GetBuffer());
+
+ // layered transports anyone?
+ switch (Layered)
+ {
+ case LayeredChoice.None:
+ Transport = MemBuffer;
+ break;
+ case LayeredChoice.Framed:
+ Transport = new TFramedTransport(MemBuffer);
+ break;
+ case LayeredChoice.Buffered:
+ Transport = new TBufferedTransport(MemBuffer);
+ break;
+ default:
+ Debug.Assert(false);
+ break;
+ }
+
+ if (!Transport.IsOpen)
+ Transport.OpenAsync().Wait();
+
+ var instance = (T)Activator.CreateInstance(typeof(T), Transport);
+ return Task.FromResult<TProtocol>(instance);
+ }
+ finally
+ {
+ if (oldTrans is IDisposable)
+ (oldTrans as IDisposable).Dispose();
+ }
+ }
+
+ private string GetProtocolTransportName(TProtocol proto)
+ {
+ var name = Transport.GetType().Name;
+ if (name.Equals(MemBuffer.GetType().Name))
+ name = string.Empty;
+ else
+ name = " + " + name;
+
+ name = proto.GetType().Name + name;
+ return name;
+ }
+
+
+ private async Task RunTestAsync(Func<bool, Task<TProtocol>> factory)
+ {
+ var stop = new Stopwatch();
+
+ var proto = await factory(true);
+ stop.Start();
+ await Testdata.WriteAsync(proto, Cancel.Token);
+ await Transport.FlushAsync(Cancel.Token);
+ stop.Stop();
+ Console.WriteLine("RunTestAsync({0}): write = {1} msec",
+ GetProtocolTransportName(proto),
+ stop.ElapsedMilliseconds);
+
+ var restored = new CrazyNesting();
+ proto = await factory(false);
+ stop.Start();
+ await restored.ReadAsync(proto, Cancel.Token);
+ stop.Stop();
+ Console.WriteLine("RunTestAsync({0}): read = {1} msec",
+ GetProtocolTransportName(proto),
+ stop.ElapsedMilliseconds);
+ }
+
+ }
+}
diff --git a/test/netstd/Client/Performance/TestDataFactory.cs b/test/netstd/Client/Performance/TestDataFactory.cs
new file mode 100644
index 000000000..98962857c
--- /dev/null
+++ b/test/netstd/Client/Performance/TestDataFactory.cs
@@ -0,0 +1,154 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ThriftTest;
+using Thrift.Collections;
+
+namespace Client.Tests
+{
+
+ static class TestDataFactory
+ {
+ public static CrazyNesting CreateCrazyNesting(int count = 10)
+ {
+ if (count <= 0)
+ return null;
+
+ return new CrazyNesting()
+ {
+ Binary_field = CreateBytesArray(count),
+ List_field = CreateListField(count),
+ Set_field = CreateSetField(count),
+ String_field = string.Format("data level {0}", count)
+ };
+ }
+
+ private static THashSet<Insanity> CreateSetField(int count)
+ {
+ var retval = new THashSet<Insanity>();
+ for (var i = 0; i < count; ++i)
+ retval.Add(CreateInsanity(count));
+ return retval;
+ }
+
+ private static Insanity CreateInsanity(int count)
+ {
+ return new Insanity()
+ {
+ UserMap = CreateUserMap(count),
+ Xtructs = CreateXtructs(count)
+ };
+ }
+
+ private static List<Xtruct> CreateXtructs(int count)
+ {
+ var retval = new List<Xtruct>();
+ for (var i = 0; i < count; ++i)
+ retval.Add(CreateXtruct(count));
+ return retval;
+ }
+
+ private static Xtruct CreateXtruct(int count)
+ {
+ return new Xtruct()
+ {
+ Byte_thing = (sbyte)(count % 128),
+ I32_thing = count,
+ I64_thing = count,
+ String_thing = string.Format("data level {0}", count)
+ };
+ }
+
+ private static Dictionary<Numberz, long> CreateUserMap(int count)
+ {
+ var retval = new Dictionary<Numberz, long>();
+ retval.Add(Numberz.ONE, count);
+ retval.Add(Numberz.TWO, count);
+ retval.Add(Numberz.THREE, count);
+ retval.Add(Numberz.FIVE, count);
+ retval.Add(Numberz.SIX, count);
+ retval.Add(Numberz.EIGHT, count);
+ return retval;
+ }
+
+ private static List<Dictionary<THashSet<int>, Dictionary<int, THashSet<List<Dictionary<Insanity, string>>>>>> CreateListField(int count)
+ {
+ var retval = new List<Dictionary<THashSet<int>, Dictionary<int, THashSet<List<Dictionary<Insanity, string>>>>>>();
+ for (var i = 0; i < count; ++i)
+ retval.Add(CreateListFieldData(count));
+ return retval;
+ }
+
+ private static Dictionary<THashSet<int>, Dictionary<int, THashSet<List<Dictionary<Insanity, string>>>>> CreateListFieldData(int count)
+ {
+ var retval = new Dictionary<THashSet<int>, Dictionary<int, THashSet<List<Dictionary<Insanity, string>>>>>();
+ for (var i = 0; i < count; ++i)
+ retval.Add( CreateIntHashSet(count), CreateListFieldDataDict(count));
+ return retval;
+ }
+
+ private static THashSet<int> CreateIntHashSet(int count)
+ {
+ var retval = new THashSet<int>();
+ for (var i = 0; i < count; ++i)
+ retval.Add(i);
+ return retval;
+ }
+
+ private static Dictionary<int, THashSet<List<Dictionary<Insanity, string>>>> CreateListFieldDataDict(int count)
+ {
+ var retval = new Dictionary<int, THashSet<List<Dictionary<Insanity, string>>>>();
+ for (var i = 0; i < count; ++i)
+ retval.Add(i, CreateListFieldDataDictValue(count));
+ return retval;
+ }
+
+ private static THashSet<List<Dictionary<Insanity, string>>> CreateListFieldDataDictValue(int count)
+ {
+ var retval = new THashSet<List<Dictionary<Insanity, string>>>();
+ for (var i = 0; i < count; ++i)
+ retval.Add( CreateListFieldDataDictValueList(count));
+ return retval;
+ }
+
+ private static List<Dictionary<Insanity, string>> CreateListFieldDataDictValueList(int count)
+ {
+ var retval = new List<Dictionary<Insanity, string>>();
+ for (var i = 0; i < count; ++i)
+ retval.Add(CreateListFieldDataDictValueListDict(count));
+ return retval;
+ }
+
+ private static Dictionary<Insanity, string> CreateListFieldDataDictValueListDict(int count)
+ {
+ var retval = new Dictionary<Insanity, string>();
+ retval.Add(CreateInsanity(count), string.Format("data level {0}", count));
+ return retval;
+ }
+
+ private static byte[] CreateBytesArray(int count)
+ {
+ var retval = new byte[count];
+ for (var i = 0; i < count; ++i)
+ retval[i] = (byte)(i % 0xFF);
+ return retval;
+ }
+ }
+}
diff --git a/test/netstd/Client/Program.cs b/test/netstd/Client/Program.cs
index 8d973c480..62933e62e 100644
--- a/test/netstd/Client/Program.cs
+++ b/test/netstd/Client/Program.cs
@@ -48,6 +48,8 @@ namespace Client
{
case "client":
return TestClient.Execute(subArgs);
+ case "performance":
+ return Tests.PerformanceTests.Execute();
case "--help":
PrintHelp();
return 0;
@@ -61,7 +63,8 @@ namespace Client
private static void PrintHelp()
{
Console.WriteLine("Usage:");
- Console.WriteLine(" Client client [options]'");
+ Console.WriteLine(" Client client [options]");
+ Console.WriteLine(" Client performance");
Console.WriteLine(" Client --help");
Console.WriteLine("");