using System.Threading.Tasks; namespace TestPooling { using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using DirtyList; using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration; using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions; using HeuristicLab.Problems.ProgramSynthesis.Push.Generators; using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter; using HeuristicLab.Problems.ProgramSynthesis.Push.Parser; using HeuristicLab.Problems.ProgramSynthesis.Push.Simplifier; using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; using HeuristicLab.Random; using TestPooling.Pool; class Program { private const int PartitionSize = 512; private const int ExampleCount = 200; private const int InstanceCount = 1024; private const int PopulationCount = 100; private static int TotalInstanceCount => PopulationCount * InstanceCount * ExampleCount; static void Main(string[] args) { //Test1(); //Test1_2(); //Test3(); //TestCollectionPooling(); //DirtyListTest(); //TestAddRangeNConcat(); //TestStacks(); //SimpleTest(); //Stepwise().Wait(); //PerformanceTestInterpreter(); //PerformanceParallelTestInterpreter(); //PerformanceTestLinearCodeGenerator(); TestRobustness(); //TestPool(); //TestPoolPerformance(); //TestSimplifier(); //FlagsTest(); //TestExpressionDependencies(); Console.WriteLine("\nPress any key to continue..."); Console.ReadKey(false); } private static void TestExpressionDependencies() { var enabledExpressions = ExpressionTable.GetEnabledExpressionsByStackTypes(StackTypes.Boolean | StackTypes.Integer); } private static void FlagsTest() { var types = StackTypes.Boolean | StackTypes.Char | StackTypes.Integer; StackTypes test1 = (StackTypes)(StackTypes.Boolean - types); StackTypes test2 = (StackTypes)((StackTypes.Boolean | StackTypes.Float) - types); StackTypes test3 = ((StackTypes.Boolean | StackTypes.Float) & types); StackTypes test4 = ((StackTypes.Boolean | StackTypes.Float) ^ types); StackTypes test5 = ((StackTypes.Boolean | StackTypes.Float) | types); StackTypes test6 = (StackTypes.Boolean | StackTypes.Float) & ~types; StackTypes test7 = StackTypes.Boolean & ~types; } private static void TestStacks() { var sw = new Stopwatch(); var stack = new DirtyList.PushStack(); var stack2 = new PushStack2(); var stack3 = new PushStack3(); var listC = new List(1000); var count = 200000; var repeats = 10; for (var i = 0; i < 100; i++) { listC.Add(i); } sw.Start(); for (var j = 0; j < repeats; j++) { stack.Clear(); for (int i = 0; i < count; i++) { stack.Push(listC); } } sw.Stop(); Console.WriteLine("{0}", sw.ElapsedMilliseconds / repeats); sw.Restart(); for (var j = 0; j < repeats; j++) { stack2.Clear(); for (int i = 0; i < count; i++) { stack2.PushRange(listC); } } sw.Stop(); Console.WriteLine("{0}", sw.ElapsedMilliseconds / repeats); sw.Restart(); for (var j = 0; j < repeats; j++) { stack3.Clear(); for (int i = 0; i < count; i++) { stack3.PushRange(listC); } } sw.Stop(); Console.WriteLine("{0}", sw.ElapsedMilliseconds / repeats); sw.Restart(); for (int i = 0; i < count * listC.Count; i++) { stack.Pop(); } Console.WriteLine("{0}", sw.ElapsedMilliseconds); sw.Restart(); for (int i = 0; i < count * listC.Count; i++) { stack2.Pop(); } Console.WriteLine("{0}", sw.ElapsedMilliseconds); } private static void TestAddRangeNConcat() { var sw = new Stopwatch(); var count = 10000; var listA = new List(); var listB = new List(); var listC = new List(1000); for (var i = 0; i < 1000; i++) { listC.Add(i); } sw.Start(); for (int i = 0; i < count; i++) { listA.AddRange(listC); } sw.Stop(); Console.WriteLine("{0}", sw.ElapsedMilliseconds); sw.Restart(); for (int i = 0; i < count; i++) { listB = listB.Concat(listC).ToList(); } sw.Stop(); Console.WriteLine("{0}", sw.ElapsedMilliseconds); } private static void DirtyListTest() { var sw = new Stopwatch(); var provider = new ManagedPoolProvider(100, () => new Person()); var provider2 = new ManagedPoolProvider(100, () => new Person()); var dl = new DirtyList(); var l = new List(); sw.Start(); for (var i = 0; i < 30000000; i++) { using (var pool = provider.CreatePool()) { for (var j = 0; j < 2; j++) { var person = pool.Get(); person.Age = i + j; person.Name = (i + j).ToString(); dl.Add(person); } } dl.Clear(); } sw.Stop(); Console.WriteLine("DirtyList: {0}", sw.Elapsed.TotalSeconds); sw.Restart(); for (var i = 0; i < 30000000; i++) { using (var pool = provider2.CreatePool()) { for (var j = 0; j < 2; j++) { var person = pool.Get(); person.Age = i + j; person.Name = (i + j).ToString(); l.Add(person); } } l.Clear(); } sw.Stop(); Console.WriteLine("List: {0}", sw.Elapsed.TotalSeconds); } private static void TestCollectionPooling() { var sw = new Stopwatch(); sw.Start(); var provider = new ManagedPoolProvider>(PartitionSize, () => new PooledList()); Parallel.For(0, PopulationCount, pc => { for (var e = 0; e < ExampleCount; e++) { using (var pool = provider.CreatePool()) { var list = pool.Get(); for (var i = 0; i < InstanceCount; i++) list.Add(new Person { Age = pc + e + i, Name = string.Format("{0} - {1} - {2}", pc, e, i) }); } } }); sw.Stop(); Console.WriteLine("Collection Pooling - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, provider.InstanceCount, TotalInstanceCount); } private static void Test1() { var sw = new Stopwatch(); sw.Start(); Parallel.For(0, PopulationCount, pc => { for (var e = 0; e < ExampleCount; e++) { using (var pool = new ManagedPool(PartitionSize, () => new Person())) { for (var i = 0; i < InstanceCount; i++) { var person = pool.Get(); person.Age = pc + e + i; person.Name = string.Format("{0} - {1} - {2}", pc, e, i); } } } }); sw.Stop(); Console.WriteLine("1 - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, ManagedPool.InstanceCount, TotalInstanceCount); } private static void Test1_2() { var sw = new Stopwatch(); sw.Start(); var provider = new ManagedPoolProvider(PartitionSize, () => new Person()); Parallel.For(0, PopulationCount, pc => { for (var e = 0; e < ExampleCount; e++) { using (var pool = provider.CreatePool()) { for (var i = 0; i < InstanceCount; i++) { var person = pool.Get(); person.Age = pc + e + i; person.Name = string.Format("{0} - {1} - {2}", pc, e, i); } } } }); sw.Stop(); Console.WriteLine("1_2 - Duration: {0} - {1} for {2}/{3} instances", sw.ElapsedTicks, sw.Elapsed.TotalSeconds, provider.InstanceCount, TotalInstanceCount); } private static void Test3() { var count = 0; var sw = new Stopwatch(); sw.Start(); Parallel.For(0, PopulationCount, pc => { for (var e = 0; e < ExampleCount; e++) { var list = new Person[InstanceCount]; for (var i = 0; i < InstanceCount; i++) { list[i] = new Person { Age = pc + e + i, Name = string.Format("{0} - {1} - {2}", pc, e, i) }; } Interlocked.Add(ref count, list.Length); } }); sw.Stop(); Console.WriteLine("3 - Duration: {0} - {1}", sw.ElapsedTicks, sw.Elapsed.TotalSeconds); Console.WriteLine("PartitionSize: {0}", count); } private static void Test2() { var pool = new ObjectPool(() => new Person(), 2048); Parallel.For(0, 10000, i => { for (var j = 0; j < 3000; j++) { var person = pool.Allocate(); person.Age = i + j; person.Name = string.Format("{0} - {1}", i, j); } //pool.Free() }); } static void SimpleTest() { var interpreter = new PushInterpreter(); interpreter.Run("5 INTEGER.DUP INTEGER.+"); interpreter.PrintStacks(); } static async Task Stepwise() { var interpreter = new PushInterpreter(); interpreter.RunAsync("( 0 2 CODE.QUOTE ( 1 INTEGER.+ 0 3 CODE.QUOTE ( 1 INTEGER.+ INTEGER.* ) CODE.DO*RANGE INTEGER.+ ) CODE.DO*RANGE )", true).Wait(); while (!interpreter.IsCompleted) { Console.Clear(); interpreter.PrintStacks(); interpreter.Step(); var input = Console.ReadKey(); if (input.Key == ConsoleKey.Escape) { break; } else if (input.Key == ConsoleKey.Spacebar) { await interpreter.ResumeAsync(); } } Console.Clear(); interpreter.PrintStacks(); } static void PerformanceTestInterpreter() { var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )"); var interpreter = new PushInterpreter(); var sw = new Stopwatch(); sw.Start(); for (var i = 0; i < 60000000; i++) { interpreter.Run(program); interpreter.Clear(); } sw.Stop(); Console.WriteLine(sw.Elapsed); } static void PerformanceParallelTestInterpreter() { var program = PushParser.Parse("( 5 INTEGER.DUP INTEGER.+ )"); var sw = new Stopwatch(); var iterations = 100; var amount = 600000; var pool = new PushInterpreterPool(iterations, 1024); sw.Start(); Parallel.For(0, iterations, i => { using (var interpreter = pool.Create()) { for (var j = 0; j < amount; j++) { interpreter.Run(program); interpreter.Clear(); } } }); sw.Stop(); Console.WriteLine(sw.Elapsed); } static void PerformanceTestRecursiveCodeGenerator() { var sw = new Stopwatch(); var random = new FastRandom(1337); sw.Start(); var expressions = RecursiveCodeGenerator.RandomCode(60000000, random).ToList(); sw.Stop(); Console.WriteLine("Generated {0} in {1}", expressions.Count, sw.Elapsed); } static void PerformanceTestLinearCodeGenerator() { var sw = new Stopwatch(); var random = new FastRandom(1337); var poolProvider = new ManagedPoolProvider>(65636, () => new PooledList()); sw.Start(); var expressions = LinearCodeGenerator.RandomCode(60000000, null, random).ToList(); sw.Stop(); Console.WriteLine("Generated {0} in {1}", expressions.Count, sw.Elapsed); } static void TestRobustness() { var sw = new Stopwatch(); var parallelism = Environment.ProcessorCount; var maxProgramSizeLimit = 1024; var partitionSize = 100000; var execCounters = new int[parallelism]; var config = new PushConfiguration { EvalPushLimit = 1024, MaxPointsInProgram = 1024, IsCodeStackEnabled = false, IsExecStackEnabled = false, IsBooleanStackEnabled = false, IsFloatStackEnabled = false, IsIntegerStackEnabled = false, IsNameStackEnabled = false, }; config.DisableExpression(); var pool = new PushInterpreterPool(config); sw.Start(); Parallel.For(0, parallelism, i => { var random = new FastRandom(1337); using (var interpreter = pool.Create(random)) { for (var j = 0; j < partitionSize; j++) { var program = LinearCodeGenerator.RandomProgram(maxProgramSizeLimit, random, config); interpreter.Run(program); execCounters[i] += interpreter.ExecCounter; interpreter.Clear(); } } }); sw.Stop(); Console.WriteLine("ExecCount: {0}", execCounters.Sum()); Console.WriteLine("Duration: {0}", sw.Elapsed); } static void TestPool() { var pool = new PushInterpreterPool(); var normal = new PushInterpreter(); int id; using (var interpreter = pool.Create()) { interpreter.Run("( 1 2 INTEGER.+ )"); id = interpreter.GetHashCode(); if (id == normal.GetHashCode()) Console.WriteLine("equal 1"); } using (var interpreter = pool.Create()) using (var interpreter2 = pool.Create()) { interpreter.Run("( 1 2 INTEGER.+ )"); if (id == interpreter.GetHashCode()) Console.WriteLine("equal 2"); if (id == interpreter2.GetHashCode()) Console.WriteLine("equal 3"); } } static void TestPoolPerformance() { var sw = new Stopwatch(); var iterations = 100000000; sw.Start(); for (var i = 0; i < iterations; i++) { var interpreter = new PushInterpreter(); interpreter.Clear(); } sw.Stop(); Console.WriteLine(sw.Elapsed); var pool = new PushInterpreterPool(); sw.Restart(); for (var i = 0; i < iterations; i++) { using (var interpreter = pool.Create()) { interpreter.Clear(); } } sw.Stop(); Console.WriteLine(sw.Elapsed); } static void TestSimplifier() { var program = PushParser.ParseProgram("( 5 ( INTEGER.DUP FLOAT.+ FLOAT.- ) ( EXEC.DO ( EXEC.IF ) EXEC.Y ) INTEGER.+ )"); var pool = new PushInterpreterPool(); var random = new FastRandom(1337); var randomProg = LinearCodeGenerator.RandomProgram(4096 * 4, random); // 53 Func evaluator = prog => { using (var interpreter = pool.Create(random)) { interpreter.Run(prog); return interpreter.IntegerStack.IsEmpty ? double.MaxValue : Math.Abs(interpreter.IntegerStack.Top - 10); } }; var simplerProgram = Simplifier.Simplify(program, evaluator); Console.WriteLine(simplerProgram); } } [Serializable] class Person : IPooledObject { public string Name { get; set; } public int Age { get; set; } public void Reset() { Age = default(int); Name = null; } } }