diff options
Diffstat (limited to 'tests/src/JIT')
28 files changed, 2451 insertions, 0 deletions
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees-best.cs new file mode 100644 index 0000000000..f559a51081 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees-best.cs @@ -0,0 +1,105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from binary-trees C# .NET Core #5 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=csharpcore&id=5 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Marek Safar + *reset* + concurrency added by Peperud + minor improvements by Alex Yakunin +*/ + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +public sealed class BinaryTrees +{ + public const int MinDepth = 4; + + public static void Main(string[] args) + { + var n = args.Length == 0 ? 0 : int.Parse(args[0]); + var maxDepth = n < (MinDepth + 2) ? MinDepth + 2 : n; + var stretchDepth = maxDepth + 1; + + var stretchDepthTask = Task.Run(() => TreeNode.CreateTree(stretchDepth).CountNodes()); + var maxDepthTask = Task.Run(() => TreeNode.CreateTree(maxDepth).CountNodes()); + + var tasks = new Task<string>[(maxDepth - MinDepth) / 2 + 1]; + for (int depth = MinDepth, ti = 0; depth <= maxDepth; depth += 2, ti++) { + var iterationCount = 1 << (maxDepth - depth + MinDepth); + var depthCopy = depth; // To make sure closure value doesn't change + tasks[ti] = Task.Run(() => { + var count = 0; + if (depthCopy >= 17) { + // Parallelized computation for relatively large tasks + var miniTasks = new Task<int>[iterationCount]; + for (var i = 0; i < iterationCount; i++) + miniTasks[i] = Task.Run(() => TreeNode.CreateTree(depthCopy).CountNodes()); + Task.WaitAll(miniTasks); + for (var i = 0; i < iterationCount; i++) + count += miniTasks[i].Result; + } + else { + // Sequential computation for smaller tasks + for (var i = 0; i < iterationCount; i++) + count += TreeNode.CreateTree(depthCopy).CountNodes(); + } + return $"{iterationCount}\t trees of depth {depthCopy}\t check: {count}"; + }); + } + Task.WaitAll(tasks); + + Console.WriteLine("stretch tree of depth {0}\t check: {1}", + stretchDepth, stretchDepthTask.Result); + foreach (var task in tasks) + Console.WriteLine(task.Result); + Console.WriteLine("long lived tree of depth {0}\t check: {1}", + maxDepth, maxDepthTask.Result); + } +} + +public struct TreeNode +{ + public sealed class NodeData + { + public TreeNode Left, Right; + + public NodeData(TreeNode left, TreeNode right) + { + Left = left; + Right = right; + } + } + + public NodeData Data; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TreeNode(TreeNode left, TreeNode right) + { + Data = new NodeData(left, right); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TreeNode CreateTree(int depth) + { + return depth <= 0 + ? default(TreeNode) + : new TreeNode(CreateTree(depth - 1), CreateTree(depth - 1)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CountNodes() + { + if (ReferenceEquals(Data, null)) + return 1; + return 1 + Data.Left.CountNodes() + Data.Right.CountNodes(); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees-serial.cs new file mode 100644 index 0000000000..95732c6f33 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees-serial.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from binary-trees C# .NET Core #2 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=csharpcore&id=2 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Marek Safar + *reset* +*/ + +using System; + +class BinaryTrees +{ + const int minDepth = 4; + + public static void Main(String[] args) + { + int n = 0; + if (args.Length > 0) n = Int32.Parse(args[0]); + + int maxDepth = Math.Max(minDepth + 2, n); + int stretchDepth = maxDepth + 1; + + int check = (TreeNode.bottomUpTree(stretchDepth)).itemCheck(); + Console.WriteLine("stretch tree of depth {0}\t check: {1}", stretchDepth, check); + + TreeNode longLivedTree = TreeNode.bottomUpTree(maxDepth); + + for (int depth=minDepth; depth<=maxDepth; depth+=2){ + int iterations = 1 << (maxDepth - depth + minDepth); + + check = 0; + for (int i=1; i<=iterations; i++) + { + check += (TreeNode.bottomUpTree(depth)).itemCheck(); + } + + Console.WriteLine("{0}\t trees of depth {1}\t check: {2}", + iterations, depth, check); + } + + Console.WriteLine("long lived tree of depth {0}\t check: {1}", + maxDepth, longLivedTree.itemCheck()); + } + + + struct TreeNode + { + class Next + { + public TreeNode left, right; + } + + private Next next; + + internal static TreeNode bottomUpTree(int depth){ + if (depth>0){ + return new TreeNode( + bottomUpTree(depth-1) + , bottomUpTree(depth-1) + ); + } + else { + return new TreeNode(); + } + } + + TreeNode(TreeNode left, TreeNode right){ + this.next = new Next (); + this.next.left = left; + this.next.right = right; + } + + internal int itemCheck(){ + // if necessary deallocate here + if (next==null) return 1; + else return 1 + next.left.itemCheck() + next.right.itemCheck(); + } + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fannkuch-redux/fannkuch-redux-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fannkuch-redux/fannkuch-redux-best.cs new file mode 100644 index 0000000000..470b67beaf --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fannkuch-redux/fannkuch-redux-best.cs @@ -0,0 +1,127 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from fannkuch-redux C# .NET Core #5 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=csharpcore&id=5 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Isaac Gouy, transliterated from Oleg Mazurov's Java program + concurrency fix and minor improvements by Peperud + parallel and small optimisations by Anthony Lloyd +*/ + +using System; +using System.Threading; +using System.Runtime.CompilerServices; + +public static class FannkuchRedux +{ + static int[] fact, chkSums, maxFlips; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void firstPermutation(int[] p, int[] pp, int[] count, int idx) + { + for (int i = 0; i < p.Length; ++i) p[i] = i; + for (int i = count.Length - 1; i > 0; --i) + { + int d = idx / fact[i]; + count[i] = d; + if (d > 0) + { + idx = idx % fact[i]; + for (int j = i; j >= 0; --j) pp[j] = p[j]; + for (int j = 0; j <= i; ++j) p[j] = pp[(j + d) % (i + 1)]; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static int nextPermutation(int[] p, int[] count) + { + int first = p[1]; + p[1] = p[0]; + p[0] = first; + int i = 1; + while (++count[i] > i) + { + count[i++] = 0; + int next = p[1]; + p[0] = next; + for (int j = 1; j < i;) p[j] = p[++j]; + p[i] = first; + first = next; + } + return first; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static int countFlips(int first, int[] p, int[] pp) + { + if (first == 0) return 0; + if (p[first] == 0) return 1; + for (int i = 0; i < pp.Length; i++) pp[i] = p[i]; + int flips = 2; + while (true) + { + for (int lo = 1, hi = first - 1; lo < hi; lo++, hi--) + { + int t = pp[lo]; + pp[lo] = pp[hi]; + pp[hi] = t; + } + int tp = pp[first]; + if (pp[tp] == 0) return flips; + pp[first] = first; + first = tp; + flips++; + } + } + + static void run(int n, int taskId, int taskSize) + { + int[] p = new int[n], pp = new int[n], count = new int[n]; + firstPermutation(p, pp, count, taskId * taskSize); + int chksum = countFlips(p[0], p, pp); + int maxflips = chksum; + while (--taskSize > 0) + { + var flips = countFlips(nextPermutation(p, count), p, pp); + chksum += (1 - (taskSize % 2) * 2) * flips; + if (flips > maxflips) maxflips = flips; + } + chkSums[taskId] = chksum; + maxFlips[taskId] = maxflips; + } + + public static void Main(string[] args) + { + int n = args.Length > 0 ? int.Parse(args[0]) : 7; + fact = new int[n + 1]; + fact[0] = 1; + var factn = 1; + for (int i = 1; i < fact.Length; i++) { fact[i] = factn *= i; } + + int nTasks = Environment.ProcessorCount; + chkSums = new int[nTasks]; + maxFlips = new int[nTasks]; + int taskSize = factn / nTasks; + var threads = new Thread[nTasks]; + for (int i = 1; i < nTasks; i++) + { + int j = i; + (threads[j] = new Thread(() => run(n, j, taskSize))).Start(); + } + run(n, 0, taskSize); + int chksum = chkSums[0], maxflips = maxFlips[0]; + for (int i = 1; i < threads.Length; i++) + { + threads[i].Join(); + chksum += chkSums[i]; + if (maxFlips[i] > maxflips) maxflips = maxFlips[i]; + } + Console.Out.WriteLineAsync(chksum + "\nPfannkuchen(" + n + ") = " + maxflips); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fannkuch-redux/fannkuch-redux-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fannkuch-redux/fannkuch-redux-serial.cs new file mode 100644 index 0000000000..646b68d2b4 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fannkuch-redux/fannkuch-redux-serial.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from fannkuch-redux C# .NET Core #2 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=csharpcore&id=2 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Isaac Gouy, transliterated from Mike Pall's Lua program +*/ + +using System; + +class FannkuchRedux +{ + public static int[] fannkuch(int n) { + int[] p = new int[n], q = new int[n], s = new int[n]; + int sign = 1, maxflips = 0, sum = 0, m = n-1; + for(int i=0; i<n; i++){ p[i] = i; q[i] = i; s[i] = i; } + do { + // Copy and flip. + var q0 = p[0]; // Cache 0th element. + if (q0 != 0){ + for(int i=1; i<n; i++) q[i] = p[i]; // Work on a copy. + var flips = 1; + do { + var qq = q[q0]; + if (qq == 0){ // ... until 0th element is 0. + sum += sign*flips; + if (flips > maxflips) maxflips = flips; // New maximum? + break; + } + q[q0] = q0; + if (q0 >= 3){ + int i = 1, j = q0 - 1, t; + do { t = q[i]; q[i] = q[j]; q[j] = t; i++; j--; } while (i < j); + } + q0 = qq; flips++; + } while (true); + } + // Permute. + if (sign == 1){ + var t = p[1]; p[1] = p[0]; p[0] = t; sign = -1; // Rotate 0<-1. + } else { + var t = p[1]; p[1] = p[2]; p[2] = t; sign = 1; // Rotate 0<-1 and 0<-1<-2. + for(int i=2; i<n; i++){ + var sx = s[i]; + if (sx != 0){ s[i] = sx-1; break; } + if (i == m) return new int[]{sum,maxflips}; // Out of permutations. + s[i] = i; + // Rotate 0<-...<-i+1. + t = p[0]; for(int j=0; j<=i; j++){ p[j] = p[j+1]; } p[i+1] = t; + } + } + } while (true); + } + + static void Main(string[] args){ + int n = (args.Length > 0) ? Int32.Parse(args[0]) : 7; + var pf = fannkuch(n); + Console.Write("{0}\nPfannkuchen({1}) = {2}\n", pf[0], n, pf[1]); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta-best.cs new file mode 100644 index 0000000000..3430c37a6b --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta-best.cs @@ -0,0 +1,288 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from fasta C# .NET Core program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=fasta&lang=csharpcore&id=1 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Serge Smith + further optimized (rewrote threading, random generation loop) by Jan de Vaan + modified by Josh Goldfoot (fasta-repeat buffering) +*/ + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +class Fasta +{ + const int LineLength = 60; + + const int IM = 139968; + const int IA = 3877; + const int IC = 29573; + static int seed = 42; + + public static void Main(string[] args) + { + int n = args.Length > 0 ? Int32.Parse(args[0]) : 1000; + + MakeCumulative(IUB); + MakeCumulative(HomoSapiens); + + using (var s = Console.OpenStandardOutput()) + { + MakeRepeatFasta("ONE", "Homo sapiens alu", Encoding.ASCII.GetBytes(ALU), n * 2, s); + MakeRandomFasta("TWO", "IUB ambiguity codes", IUB, n * 3, s); + MakeRandomFasta("THREE", "Homo sapiens frequency", HomoSapiens, n * 5, s); + } + } + + + + public static IEnumerable<R> TransformQueue<T, R>(BlockingCollection<T> queue, + Func<T, R> transform, int threadCount) + { + var tasks = new Task<R>[threadCount]; + + for (int i = 0; i < threadCount; ++i) + { + T input; + if (!queue.TryTake(out input, Timeout.Infinite)) + break; + + tasks[i] = Task.Run(() => transform(input)); + } + + int pos = 0; + while (true) + { + if (tasks[pos] == null) + break; + + yield return tasks[pos].Result; + + T input; + tasks[pos] = queue.TryTake(out input, Timeout.Infinite) + ? Task.Run(() => transform(input)) + : null; + + pos = (pos + 1) % threadCount; + } + } + + + + static void MakeRandomFasta(string id, string desc, + Frequency[] a, int n, Stream s) + { + var queue = new BlockingCollection<int[]>(2); + + var bufferCount = Environment.ProcessorCount + 4; + + Task.Run(() => + { + var len = LineLength * 40; + var buffers = Enumerable.Range(0, bufferCount) + .Select(i => new int[len]).ToArray(); + var index = 0; + for (var i = 0; i < n; i += len) + { + var buffer = n - i < len + ? new int[n - i] + : buffers[index++ % buffers.Length]; + + FillRandom(buffer); + queue.Add(buffer); + } + queue.CompleteAdding(); + }); + + byte[] descStr = Encoding.ASCII.GetBytes(">" + id + " " + desc + "\n"); + s.Write(descStr, 0, descStr.Length); + + foreach (var r in TransformQueue(queue, + rnd => SelectNucleotides(a, rnd), Environment.ProcessorCount)) + { + s.Write(r, 0, r.Length); + } + + } + + private static byte[] SelectNucleotides(Frequency[] a, int[] rnd) + { + var resLength = (rnd.Length / LineLength) * (LineLength + 1); + if (rnd.Length % LineLength != 0) + { + resLength += rnd.Length % LineLength + 1; + } + + var buf = new byte[resLength]; + var index = 0; + for (var i = 0; i < rnd.Length; i += LineLength) + { + var len = Math.Min(LineLength, rnd.Length - i); + for (var j = 0; j < len; ++j) + buf[index++] = SelectRandom(a, (int)rnd[i + j]); + buf[index++] = (byte)'\n'; + } + return buf; + } + + static void MakeRepeatFasta(string id, string desc, + byte[] alu, int n, Stream s) + { + byte[] descStr = Encoding.ASCII.GetBytes(">" + id + " " + desc + "\n"); + s.Write(descStr, 0, descStr.Length); + + /* JG: fasta_repeat repeats every len(alu) * line-length = 287 * 61 = 17507 characters. + So, calculate this once, then just print that buffer over and over. */ + + byte[] sequence; + int sequenceLength; + using (var unstandardOut = new MemoryStream(alu.Length * (LineLength + 1) + 1)) + { + MakeRepeatFastaBuffer(alu, alu.Length * LineLength, unstandardOut); + sequenceLength = (int)unstandardOut.Length; + sequence = new byte[sequenceLength]; + unstandardOut.Seek(0, SeekOrigin.Begin); + unstandardOut.Read(sequence, 0, sequenceLength); + } + int outputBytes = n + n / 60; + while (outputBytes >= sequenceLength) + { + s.Write(sequence, 0, sequenceLength); + outputBytes -= sequenceLength; + } + if (outputBytes > 0) + { + s.Write(sequence, 0, outputBytes); + s.WriteByte((byte)'\n'); + } + } + + static void MakeRepeatFastaBuffer(byte[] alu, int n, Stream s) + { + var index = 0; + int m = 0; + int k = 0; + int kn = alu.Length; + var buf = new byte[1024]; + + while (n > 0) + { + m = n < LineLength ? n : LineLength; + + if (buf.Length - index < m) + { + s.Write(buf, 0, index); + index = 0; + } + + for (int i = 0; i < m; i++) + { + if (k == kn) + k = 0; + + buf[index++] = alu[k]; + k++; + } + + buf[index++] = (byte)'\n'; + n -= LineLength; + } + + if (index != 0) + s.Write(buf, 0, index); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static byte SelectRandom(Frequency[] a, int r) + { + for (int i = 0; i < a.Length - 1; i++) + if (r < a[i].p) + return a[i].c; + + return a[a.Length - 1].c; + } + + static void MakeCumulative(Frequency[] a) + { + double cp = 0; + for (int i = 0; i < a.Length; i++) + { + cp += a[i].p; + a[i].p = cp; + } + } + + static string ALU = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; + + struct Frequency + { + public readonly byte c; + public double p; + + public Frequency(char c, double p) + { + this.c = (byte)c; + this.p = (p * IM); + } + } + + static Frequency[] IUB = { + new Frequency ('a', 0.27) + ,new Frequency ('c', 0.12) + ,new Frequency ('g', 0.12) + ,new Frequency ('t', 0.27) + + ,new Frequency ('B', 0.02) + ,new Frequency ('D', 0.02) + ,new Frequency ('H', 0.02) + ,new Frequency ('K', 0.02) + ,new Frequency ('M', 0.02) + ,new Frequency ('N', 0.02) + ,new Frequency ('R', 0.02) + ,new Frequency ('S', 0.02) + ,new Frequency ('V', 0.02) + ,new Frequency ('W', 0.02) + ,new Frequency ('Y', 0.02) +}; + + static Frequency[] HomoSapiens = { + new Frequency ('a', 0.3029549426680) + ,new Frequency ('c', 0.1979883004921) + ,new Frequency ('g', 0.1975473066391) + ,new Frequency ('t', 0.3015094502008) +}; + + + private static void FillRandom(int[] result) + { + var s = seed; + for (var i = 0; i < result.Length; i++) + { + s = (s * IA + IC) % IM; + result[i] = s; + } + seed = s; + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta-serial.cs new file mode 100644 index 0000000000..e91c6f8dff --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta-serial.cs @@ -0,0 +1,176 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from fasta C# .NET Core #2 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=fasta&lang=csharpcore&id=2 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Isaac Gouy + optimizations by Alp Toker <alp@atoker.com> +*/ + +using System; +using System.IO; +using System.Text; + +class Fasta +{ + static void Main (string[] args) { + MakeCumulative (HomoSapiens); + MakeCumulative (IUB); + + int n = args.Length > 0 ? Int32.Parse (args[0]) : 1000; + + using (Stream s = Console.OpenStandardOutput ()) { + MakeRepeatFasta ("ONE", "Homo sapiens alu", Encoding.ASCII.GetBytes (ALU), n*2, s); + MakeRandomFasta ("TWO", "IUB ambiguity codes", IUB, n*3, s); + MakeRandomFasta ("THREE", "Homo sapiens frequency", HomoSapiens, n*5, s); + } + } + + // The usual pseudo-random number generator + + const int IM = 139968; + const int IA = 3877; + const int IC = 29573; + static int seed = 42; + + static double random (double max) + { + return max * ((seed = (seed * IA + IC) % IM) * (1.0 / IM)); + } + + // Weighted selection from alphabet + + static string ALU = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; + + class Frequency { + public byte c; + public double p; + + public Frequency (char c, double p) { + this.c = (byte)c; + this.p = p; + } + } + + static Frequency[] IUB = { + new Frequency ('a', 0.27) + ,new Frequency ('c', 0.12) + ,new Frequency ('g', 0.12) + ,new Frequency ('t', 0.27) + + ,new Frequency ('B', 0.02) + ,new Frequency ('D', 0.02) + ,new Frequency ('H', 0.02) + ,new Frequency ('K', 0.02) + ,new Frequency ('M', 0.02) + ,new Frequency ('N', 0.02) + ,new Frequency ('R', 0.02) + ,new Frequency ('S', 0.02) + ,new Frequency ('V', 0.02) + ,new Frequency ('W', 0.02) + ,new Frequency ('Y', 0.02) + }; + + static Frequency[] HomoSapiens = { + new Frequency ('a', 0.3029549426680) + ,new Frequency ('c', 0.1979883004921) + ,new Frequency ('g', 0.1975473066391) + ,new Frequency ('t', 0.3015094502008) + }; + + static void MakeCumulative (Frequency[] a) { + double cp = 0.0; + for (int i=0; i < a.Length; i++) { + cp += a[i].p; + a[i].p = cp; + } + } + + // naive + static byte SelectRandom (Frequency[] a) { + double r = random (1.0); + + for (int i=0 ; i < a.Length ; i++) + if (r < a[i].p) + return a[i].c; + + return a[a.Length-1].c; + } + + const int LineLength = 60; + static int index = 0; + static byte[] buf = new byte[1024]; + + static void MakeRandomFasta (string id, string desc, Frequency[] a, int n, Stream s) { + index = 0; + int m = 0; + + byte[] descStr = Encoding.ASCII.GetBytes (">" + id + " " + desc + "\n"); + s.Write (descStr, 0, descStr.Length); + + while (n > 0) { + m = n < LineLength ? n : LineLength; + + if (buf.Length - index < m) { + s.Write (buf, 0, index); + index = 0; + } + + for (int i = 0 ; i < m ; i++) { + buf[index++] = SelectRandom (a); + } + + buf[index++] = (byte)'\n'; + n -= LineLength; + } + + if (index != 0) + s.Write (buf, 0, index); + } + + static void MakeRepeatFasta (string id, string desc, byte[] alu, int n, Stream s) { + index = 0; + int m = 0; + int k = 0; + int kn = alu.Length; + + byte[] descStr = Encoding.ASCII.GetBytes (">" + id + " " + desc + "\n"); + s.Write (descStr, 0, descStr.Length); + + while (n > 0) { + m = n < LineLength ? n : LineLength; + + if (buf.Length - index < m) { + s.Write (buf, 0, index); + index = 0; + } + + for (int i = 0; i < m ; i++) { + if (k == kn) + k = 0; + + buf[index++] = alu[k]; + k++; + } + + buf[index++] = (byte)'\n'; + n -= LineLength; + } + + if (index != 0) + s.Write (buf, 0, index); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux-best.cs new file mode 100644 index 0000000000..691fde3aac --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux-best.cs @@ -0,0 +1 @@ +// no longer up on site
\ No newline at end of file diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-best.cs new file mode 100644 index 0000000000..2b648ddd56 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-best.cs @@ -0,0 +1,282 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from k-nucleotide C# .NET Core #9 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=knucleotide&lang=csharpcore&id=9 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + submitted by Josh Goldfoot + Modified to reduce memory and do more in parallel by Anthony Lloyd + */ + +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Runtime.CompilerServices; + +class Wrapper { public int v=1; } +public static class KNucleotide +{ + const int BLOCK_SIZE = 1024 * 1024 * 8; + static List<byte[]> threeBlocks = new List<byte[]>(); + static int threeStart, threeEnd; + static byte[] tonum = new byte[256]; + static char[] tochar = new char[] {'A', 'C', 'G', 'T'}; + + static int read(Stream stream, byte[] buffer, int offset, int count) + { + var bytesRead = stream.Read(buffer, offset, count); + return bytesRead==count ? offset+count + : bytesRead==0 ? offset + : read(stream, buffer, offset+bytesRead, count-bytesRead); + } + + static int find(byte[] buffer, byte[] toFind, int i, ref int matchIndex) + { + if(matchIndex==0) + { + i = Array.IndexOf(buffer, toFind[0], i); + if(i==-1) return -1; + matchIndex = 1; + return find(buffer, toFind, i+1, ref matchIndex); + } + else + { + int bl = buffer.Length, fl = toFind.Length; + while(i<bl && matchIndex<fl) + { + if(buffer[i++]!=toFind[matchIndex++]) + { + matchIndex = 0; + return find(buffer, toFind, i, ref matchIndex); + } + } + return matchIndex==fl ? i : -1; + } + } + + static void loadThreeData() + { + var stream = Console.OpenStandardInput(); + + // find three sequence + int matchIndex = 0; + var toFind = new [] {(byte)'>', (byte)'T', (byte)'H', (byte)'R', (byte)'E', (byte)'E'}; + var buffer = new byte[BLOCK_SIZE]; + do + { + threeEnd = read(stream, buffer, 0, BLOCK_SIZE); + threeStart = find(buffer, toFind, 0, ref matchIndex); + } while (threeStart==-1); + + // Skip to end of line + matchIndex = 0; + toFind = new [] {(byte)'\n'}; + threeStart = find(buffer, toFind, threeStart, ref matchIndex); + while(threeStart==-1) + { + threeEnd = read(stream, buffer, 0, BLOCK_SIZE); + threeStart = find(buffer, toFind, 0, ref matchIndex); + } + threeBlocks.Add(buffer); + + if(threeEnd!=BLOCK_SIZE) // Needs to be at least 2 blocks + { + var bytes = threeBlocks[0]; + for(int i=threeEnd; i<bytes.Length; i++) + bytes[i] = 255; + threeEnd = 0; + threeBlocks.Add(Array.Empty<byte>()); + return; + } + + // find next seq or end of input + matchIndex = 0; + toFind = new [] {(byte)'>'}; + threeEnd = find(buffer, toFind, threeStart, ref matchIndex); + while(threeEnd==-1) + { + buffer = new byte[BLOCK_SIZE]; + var bytesRead = read(stream, buffer, 0, BLOCK_SIZE); + threeEnd = bytesRead==BLOCK_SIZE ? find(buffer, toFind, 0, ref matchIndex) + : bytesRead; + threeBlocks.Add(buffer); + } + + if(threeStart+18>BLOCK_SIZE) // Key needs to be in the first block + { + byte[] block0 = threeBlocks[0], block1 = threeBlocks[1]; + Buffer.BlockCopy(block0, threeStart, block0, threeStart-18, BLOCK_SIZE-threeStart); + Buffer.BlockCopy(block1, 0, block0, BLOCK_SIZE-18, 18); + for(int i=0; i<18; i++) block1[i] = 255; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void check(Dictionary<long, Wrapper> dict, ref long rollingKey, byte nb, long mask) + { + if(nb==255) return; + rollingKey = ((rollingKey & mask) << 2) | nb; + Wrapper w; + if (dict.TryGetValue(rollingKey, out w)) + w.v++; + else + dict[rollingKey] = new Wrapper(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void checkEnding(Dictionary<long, Wrapper> dict, ref long rollingKey, byte b, byte nb, long mask) + { + if(nb==b) + { + Wrapper w; + if (dict.TryGetValue(rollingKey, out w)) + w.v++; + else + dict[rollingKey] = new Wrapper(); + rollingKey = ((rollingKey << 2) | nb) & mask; + } + else if(nb!=255) + { + rollingKey = ((rollingKey << 2) | nb) & mask; + } + } + + static Task<string> count(int l, long mask, Func<Dictionary<long,Wrapper>,string> summary) + { + return Task.Run(() => + { + long rollingKey = 0; + var firstBlock = threeBlocks[0]; + var start = threeStart; + while(--l>0) rollingKey = (rollingKey<<2) | firstBlock[start++]; + var dict = new Dictionary<long,Wrapper>(); + for(int i=start; i<firstBlock.Length; i++) + check(dict, ref rollingKey, firstBlock[i], mask); + + int lastBlockId = threeBlocks.Count-1; + for(int bl=1; bl<lastBlockId; bl++) + { + var bytes = threeBlocks[bl]; + for(int i=0; i<bytes.Length; i++) + check(dict, ref rollingKey, bytes[i], mask); + } + + var lastBlock = threeBlocks[lastBlockId]; + for(int i=0; i<threeEnd; i++) + check(dict, ref rollingKey, lastBlock[i], mask); + return summary(dict); + }); + } + + static Dictionary<long,Wrapper> countEnding(int l, long mask, byte b) + { + long rollingKey = 0; + var firstBlock = threeBlocks[0]; + var start = threeStart; + while(--l>0) rollingKey = (rollingKey<<2) | firstBlock[start++]; + var dict = new Dictionary<long,Wrapper>(); + for(int i=start; i<firstBlock.Length; i++) + checkEnding(dict, ref rollingKey, b, firstBlock[i], mask); + + int lastBlockId = threeBlocks.Count-1; + for(int bl=1; bl<lastBlockId; bl++) + { + var bytes = threeBlocks[bl]; + for(int i=0; i<bytes.Length; i++) + checkEnding(dict, ref rollingKey, b, bytes[i], mask); + } + + var lastBlock = threeBlocks[lastBlockId]; + for(int i=0; i<threeEnd; i++) + checkEnding(dict, ref rollingKey, b, lastBlock[i], mask); + return dict; + } + + static Task<string> count4(int l, long mask, Func<Dictionary<long,Wrapper>,string> summary) + { + return Task.Factory.ContinueWhenAll( + new [] { + Task.Run(() => countEnding(l, mask, 0)), + Task.Run(() => countEnding(l, mask, 1)), + Task.Run(() => countEnding(l, mask, 2)), + Task.Run(() => countEnding(l, mask, 3)) + } + , dicts => { + var d = new Dictionary<long,Wrapper>(dicts.Sum(i => i.Result.Count)); + for(int i=0; i<dicts.Length; i++) + foreach(var kv in dicts[i].Result) + d[(kv.Key << 2) | (long)i] = kv.Value; + return summary(d); + }); + } + + static string writeFrequencies(Dictionary<long,Wrapper> freq, int fragmentLength) + { + var sb = new StringBuilder(); + double percent = 100.0 / freq.Values.Sum(i => i.v); + foreach(var kv in freq.OrderByDescending(i => i.Value.v)) + { + var keyChars = new char[fragmentLength]; + var key = kv.Key; + for (int i=keyChars.Length-1; i>=0; --i) + { + keyChars[i] = tochar[key & 0x3]; + key >>= 2; + } + sb.Append(keyChars); + sb.Append(" "); + sb.AppendLine((kv.Value.v * percent).ToString("F3")); + } + return sb.ToString(); + } + + static string writeCount(Dictionary<long,Wrapper> dictionary, string fragment) + { + long key = 0; + for (int i=0; i<fragment.Length; ++i) + key = (key << 2) | tonum[fragment[i]]; + Wrapper w; + var n = dictionary.TryGetValue(key, out w) ? w.v : 0; + return string.Concat(n.ToString(), "\t", fragment); + } + + public static void Main(string[] args) + { + tonum['c'] = 1; tonum['C'] = 1; + tonum['g'] = 2; tonum['G'] = 2; + tonum['t'] = 3; tonum['T'] = 3; + tonum['\n'] = 255; tonum['>'] = 255; tonum[255] = 255; + + loadThreeData(); + + Parallel.ForEach(threeBlocks, bytes => + { + for(int i=0; i<bytes.Length; i++) + bytes[i] = tonum[bytes[i]]; + }); + + var task18 = count4(18, 34359738367, d => writeCount(d, "GGTATTTTAATTTATAGT")); + var task12 = count4(12, 8388607, d => writeCount(d, "GGTATTTTAATT")); + var task6 = count(6, 0b1111111111, d => writeCount(d, "GGTATT")); + var task4 = count(4, 0b111111, d => writeCount(d, "GGTA")); + var task3 = count(3, 0b1111, d => writeCount(d, "GGT")); + var task2 = count(2, 0b11, d => writeFrequencies(d, 2)); + var task1 = count(1, 0, d => writeFrequencies(d, 1)); + + Console.Out.WriteLineAsync(task1.Result); + Console.Out.WriteLineAsync(task2.Result); + Console.Out.WriteLineAsync(task3.Result); + Console.Out.WriteLineAsync(task4.Result); + Console.Out.WriteLineAsync(task6.Result); + Console.Out.WriteLineAsync(task12.Result); + Console.Out.WriteLineAsync(task18.Result); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-serial.cs new file mode 100644 index 0000000000..b5add5fe00 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/k-nucleotide-serial.cs @@ -0,0 +1,165 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from k-nucleotide C# .NET Core program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=knucleotide&lang=csharpcore&id=1 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + * + * byte processing version using C# *3.0 idioms by Robert F. Tobler + */ + +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; + +public struct ByteString : IEquatable<ByteString> +{ + public byte[] Array; + public int Start; + public int Length; + + public ByteString(byte[] array, int start, int length) + { + Array = array; Start = start; Length = length; + } + + public ByteString(string text) + { + Start = 0; Length = text.Length; + Array = Encoding.ASCII.GetBytes(text); + } + + public override int GetHashCode() + { + if (Length < 1) return 0; + int hc = Length ^ (Array[Start] << 24); if (Length < 2) return hc; + hc ^= Array[Start+Length-1] << 20; if (Length < 3) return hc; + for (int c = Length-2; c > 0; c--) + hc ^= Array[Start + c] << (c & 0xf); + return hc; + } + + public bool Equals(ByteString other) + { + if (Length != other.Length) return false; + for (int i = 0; i < Length; i++) + if (Array[Start+i] != other.Array[other.Start+i]) return false; + return true; + } + + public override string ToString() + { + return Encoding.ASCII.GetString(Array, Start, Length); + } +} + +public static class Extensions +{ + public static byte[] GetBytes(this List<string> input) + { + int count = 0; + for (int i = 0; i < input.Count; i++) count += input[i].Length; + var byteArray = new byte[count]; + count = 0; + for (int i = 0; i < input.Count; i++) + { + string line = input[i]; + Encoding.ASCII.GetBytes(line, 0, line.Length, byteArray, count); + count += line.Length; + } + return byteArray; + } +} + +public class program { + + + public static void Main(string[] args) { + string line; + StreamReader source = new StreamReader(Console.OpenStandardInput()); + var input = new List<string>(); + + while ( (line = source.ReadLine() ) != null ) + if (line[0] == '>' && line.Substring(1, 5) == "THREE") + break; + + while ( (line = source.ReadLine()) != null ) { + char c = line[0]; + if (c == '>') break; + if (c != ';') input.Add(line.ToUpper()); + } + + KNucleotide kn = new KNucleotide(input.GetBytes()); + input = null; + for (int f = 1; f < 3; f++) kn.WriteFrequencies(f); + foreach (var seq in + new[] { "GGT", "GGTA", "GGTATT", "GGTATTTTAATT", + "GGTATTTTAATTTATAGT"}) + kn.WriteCount(seq); + + } +} + +public class KNucleotide { + + private class Count { + public int V; + public Count(int v) { V = v; } + } + + private Dictionary<ByteString, Count> frequencies + = new Dictionary<ByteString, Count>(); + private byte[] sequence; + + public KNucleotide(byte[] s) { sequence = s; } + + public void WriteFrequencies(int length) { + GenerateFrequencies(length); + var items = new List<KeyValuePair<ByteString, Count>>(frequencies); + items.Sort(SortByFrequencyAndCode); + double percent = 100.0 / (sequence.Length - length + 1); + foreach (var item in items) + Console.WriteLine("{0} {1:f3}", + item.Key.ToString(), item.Value.V * percent); + Console.WriteLine(); + } + + public void WriteCount(string fragment) { + GenerateFrequencies(fragment.Length); + Count count; + if (!frequencies.TryGetValue(new ByteString(fragment), out count)) + count = new Count(0); + Console.WriteLine("{0}\t{1}", count.V, fragment); + } + + private void GenerateFrequencies(int length) { + frequencies.Clear(); + for (int frame = 0; frame < length; frame++) + KFrequency(frame, length); + } + + private void KFrequency(int frame, int k) { + int n = sequence.Length - k + 1; + for (int i = frame; i < n; i += k) { + var key = new ByteString(sequence, i, k); + Count count; + if (frequencies.TryGetValue(key, out count)) + count.V++; + else + frequencies[key] = new Count(1); + } + } + + int SortByFrequencyAndCode( + KeyValuePair<ByteString, Count> i0, + KeyValuePair<ByteString, Count> i1) { + int order = i1.Value.V.CompareTo(i0.Value.V); + if (order != 0) return order; + return i0.Key.ToString().CompareTo(i1.Key.ToString()); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/mandelbrot/mandelbrot-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/mandelbrot/mandelbrot-best.cs new file mode 100644 index 0000000000..9e6912a691 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/mandelbrot/mandelbrot-best.cs @@ -0,0 +1,72 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from mandelbrot C# .NET Core #4 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=mandelbrot&lang=csharpcore&id=4 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + started with Java #2 program (Krause/Whipkey/Bennet/AhnTran/Enotus/Stalcup) + adapted for C# by Jan de Vaan + simplified and optimised to use TPL by Anthony Lloyd +*/ + +using System; +using System.Threading.Tasks; +using System.IO; +using System.Runtime.CompilerServices; + +public class MandelBrot +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static byte getByte(double[] Crb, double Ciby, int x, int y) + { + int res=0; + for(int i=0;i<8;i+=2) + { + double Crbx=Crb[x+i], Crbx1=Crb[x+i+1]; + double Zr1=Crbx, Zr2=Crbx1; + double Zi1=Ciby, Zi2=Ciby; + + int b=0; + int j=49; + do + { + double nZr1=Zr1*Zr1-Zi1*Zi1+Crbx; + Zi1=Zr1*Zi1+Zr1*Zi1+Ciby; + Zr1=nZr1; + + double nZr2=Zr2*Zr2-Zi2*Zi2+Crbx1; + Zi2=Zr2*Zi2+Zr2*Zi2+Ciby; + Zr2=nZr2; + + if(Zr1*Zr1+Zi1*Zi1>4){b|=2;if(b==3)break;} + if(Zr2*Zr2+Zi2*Zi2>4){b|=1;if(b==3)break;} + } while(--j>0); + res=(res<<2)+b; + } + return (byte)(res^-1); + } + + public static void Main (String[] args) + { + var n = args.Length > 0 ? Int32.Parse(args[0]) : 200; + double invN=2.0/n; + var Crb = new double[n+7]; + for(int i=0;i<n;i++){ Crb[i]=i*invN-1.5; } + int lineLen = (n-1)/8 + 1; + var data = new byte[n*lineLen]; + Parallel.For(0, n, y => + { + var Ciby = y*invN-1.0; + var offset = y*lineLen; + for(int x=0; x<lineLen; x++) + data[offset+x] = getByte(Crb, Ciby, x*8, y); + }); + Console.Out.WriteLine("P4\n{0} {0}", n); + Console.OpenStandardOutput().Write(data, 0, data.Length); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/mandelbrot/mandelbrot-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/mandelbrot/mandelbrot-serial.cs new file mode 100644 index 0000000000..66748b3751 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/mandelbrot/mandelbrot-serial.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from mandelbrot C# .NET Core #2 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=mandelbrot&lang=csharpcore&id=2 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + * + * Adapted by Antti Lankila from the earlier Isaac Gouy's implementation + */ + +using System; +using System.IO; + +class Mandelbrot { + + public static void Main(String[] args) { + + int width = 100; + if (args.Length > 0) + width = Int32.Parse(args[0]); + + int height = width; + int maxiter = 50; + double limit = 4.0; + + Console.WriteLine("P4"); + Console.WriteLine("{0} {1}", width,height); + Stream s = Console.OpenStandardOutput(1024); + + for (int y = 0; y < height; y++) { + int bits = 0; + int xcounter = 0; + double Ci = 2.0*y/height - 1.0; + + for (int x = 0; x < width; x++){ + double Zr = 0.0; + double Zi = 0.0; + double Cr = 2.0*x/width - 1.5; + int i = maxiter; + + bits = bits << 1; + do { + double Tr = Zr*Zr - Zi*Zi + Cr; + Zi = 2.0*Zr*Zi + Ci; + Zr = Tr; + if (Zr*Zr + Zi*Zi > limit) { + bits |= 1; + break; + } + } while (--i > 0); + + if (++xcounter == 8) { + s.WriteByte((byte) (bits ^ 0xff)); + bits = 0; + xcounter = 0; + } + } + if (xcounter != 0) + s.WriteByte((byte) ((bits << (8 - xcounter)) ^ 0xff)); + } + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body-best.cs new file mode 100644 index 0000000000..2d5ec96ee6 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body-best.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from n-body C# .NET Core #3 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=csharpcore&id=3 +// Best-scoring C# .NET Core version as of 2017-09-01 +// (also best-scoring single-threaded C# .NET Core version as of 2017-09-01) + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Isaac Gouy, optimization and use of more C# idioms by Robert F. Tobler +*/ + +using System; + +class NBody { + public static void Main(String[] args) { + int n = args.Length > 0 ? Int32.Parse(args[0]) : 10000; + NBodySystem bodies = new NBodySystem(); + Console.WriteLine("{0:f9}", bodies.Energy()); + for (int i = 0; i < n; i++) bodies.Advance(0.01); + Console.WriteLine("{0:f9}", bodies.Energy()); + } +} + +class Body { public double x, y, z, vx, vy, vz, mass; } +class Pair { public Body bi, bj; } + +class NBodySystem { + private Body[] bodies; + private Pair[] pairs; + + const double Pi = 3.141592653589793; + const double Solarmass = 4 * Pi * Pi; + const double DaysPeryear = 365.24; + + public NBodySystem() { + bodies = new Body[] { + new Body() { // Sun + mass = Solarmass, + }, + new Body() { // Jupiter + x = 4.84143144246472090e+00, + y = -1.16032004402742839e+00, + z = -1.03622044471123109e-01, + vx = 1.66007664274403694e-03 * DaysPeryear, + vy = 7.69901118419740425e-03 * DaysPeryear, + vz = -6.90460016972063023e-05 * DaysPeryear, + mass = 9.54791938424326609e-04 * Solarmass, + }, + new Body() { // Saturn + x = 8.34336671824457987e+00, + y = 4.12479856412430479e+00, + z = -4.03523417114321381e-01, + vx = -2.76742510726862411e-03 * DaysPeryear, + vy = 4.99852801234917238e-03 * DaysPeryear, + vz = 2.30417297573763929e-05 * DaysPeryear, + mass = 2.85885980666130812e-04 * Solarmass, + }, + new Body() { // Uranus + x = 1.28943695621391310e+01, + y = -1.51111514016986312e+01, + z = -2.23307578892655734e-01, + vx = 2.96460137564761618e-03 * DaysPeryear, + vy = 2.37847173959480950e-03 * DaysPeryear, + vz = -2.96589568540237556e-05 * DaysPeryear, + mass = 4.36624404335156298e-05 * Solarmass, + }, + new Body() { // Neptune + x = 1.53796971148509165e+01, + y = -2.59193146099879641e+01, + z = 1.79258772950371181e-01, + vx = 2.68067772490389322e-03 * DaysPeryear, + vy = 1.62824170038242295e-03 * DaysPeryear, + vz = -9.51592254519715870e-05 * DaysPeryear, + mass = 5.15138902046611451e-05 * Solarmass, + }, + }; + + pairs = new Pair[bodies.Length * (bodies.Length-1)/2]; + int pi = 0; + for (int i = 0; i < bodies.Length-1; i++) + for (int j = i+1; j < bodies.Length; j++) + pairs[pi++] = new Pair() { bi = bodies[i], bj = bodies[j] }; + + double px = 0.0, py = 0.0, pz = 0.0; + foreach (var b in bodies) { + px += b.vx * b.mass; py += b.vy * b.mass; pz += b.vz * b.mass; + } + var sol = bodies[0]; + sol.vx = -px/Solarmass; sol.vy = -py/Solarmass; sol.vz = -pz/Solarmass; + } + + public void Advance(double dt) { + foreach (var p in pairs) { + Body bi = p.bi, bj = p.bj; + double dx = bi.x - bj.x, dy = bi.y - bj.y, dz = bi.z - bj.z; + double d2 = dx * dx + dy * dy + dz * dz; + double mag = dt / (d2 * Math.Sqrt(d2)); + bi.vx -= dx * bj.mass * mag; bj.vx += dx * bi.mass * mag; + bi.vy -= dy * bj.mass * mag; bj.vy += dy * bi.mass * mag; + bi.vz -= dz * bj.mass * mag; bj.vz += dz * bi.mass * mag; + } + foreach (var b in bodies) { + b.x += dt * b.vx; b.y += dt * b.vy; b.z += dt * b.vz; + } + } + + public double Energy() { + double e = 0.0; + for (int i = 0; i < bodies.Length; i++) { + var bi = bodies[i]; + e += 0.5 * bi.mass * (bi.vx*bi.vx + bi.vy*bi.vy + bi.vz*bi.vz); + for (int j = i+1; j < bodies.Length; j++) { + var bj = bodies[j]; + double dx = bi.x - bj.x, dy = bi.y - bj.y, dz = bi.z - bj.z; + e -= (bi.mass * bj.mass) / Math.Sqrt(dx*dx + dy*dy + dz*dz); + } + } + return e; + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body-serial.cs new file mode 100644 index 0000000000..6d7970df3f --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body-serial.cs @@ -0,0 +1,2 @@ +// best is serial + diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csproj b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body.csproj index 5df299a93e..5df299a93e 100644 --- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csproj +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/n-body.csproj diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/nbody.csharp-3.cs index 60e083ad11..60e083ad11 100644 --- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/n-body/nbody.csharp-3.cs diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pidigits-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pidigits-best.cs new file mode 100644 index 0000000000..f9078e51be --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pidigits-best.cs @@ -0,0 +1,172 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from pidigits C# .NET Core #3 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&lang=csharpcore&id=3 +// Best-scoring C# .NET Core version as of 2017-09-01 +// (also best-scoring single-threaded C# .NET Core version as of 2017-09-01) + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + * + * Port of the Java port that uses native GMP to use native GMP with C# + * contributed by Miguel de Icaza, based on the Java version, that was: + * contributed by Mike Pall + * java port by Stefan Krause +*/ +using System; +using System.Text; +using System.Runtime.InteropServices; + +public class pidigits { + + GmpInteger q = new GmpInteger(), r = new GmpInteger(), s = new GmpInteger(), t = new GmpInteger(); + GmpInteger u = new GmpInteger(), v = new GmpInteger(), w = new GmpInteger(); + + int i; + StringBuilder strBuf = new StringBuilder (40); + int n; + + pidigits (int n) + { + this.n=n; + } + + private void compose_r(int bq, int br, int bs, int bt) + { + u.mul(r, bs); + r.mul(r, bq); + v.mul(t, br); + r.add(r, v); + t.mul(t, bt); + t.add(t, u); + s.mul(s, bt); + u.mul(q, bs); + s.add(s, u); + q.mul(q, bq); + } + + /* Compose matrix with numbers on the left. */ + private void compose_l(int bq, int br, int bs, int bt) + { + r.mul(r, bt); + u.mul(q, br); + r.add(r, u); + u.mul(t, bs); + t.mul(t, bt); + v.mul(s, br); + t.add(t, v); + s.mul(s, bq); + s.add(s, u); + q.mul(q, bq); + } + + /* Extract one digit. */ + private int extract(int j) + { + u.mul(q, j); + u.add(u, r); + v.mul(s, j); + v.add(v, t); + w.div(u, v); + return w.intValue(); + } + + /* Print one digit. Returns 1 for the last digit. */ + private bool prdigit(int y) + { + strBuf.Append(y); + if (++i % 10 == 0 || i == n) { + if (i%10!=0) for (int j=10-(i%10);j>0;j--) { strBuf.Append(" "); } + strBuf.Append("\t:"); + strBuf.Append(i); + Console.WriteLine(strBuf); + strBuf = new StringBuilder(40); + } + return i == n; + } + + /* Generate successive digits of PI. */ + void Run() + { + int k = 1; + i = 0; + q.set(1); + r.set(0); + s.set(0); + t.set(1); + for (;;) { + int y = extract(3); + if (y == extract(4)) { + if (prdigit(y)) return; + compose_r(10, -10*y, 0, 1); + } else { + compose_l(k, 4*k+2, 0, 2*k+1); + k++; + } + } + } + + public static void Main(String[] args) { + pidigits m = new pidigits(Int32.Parse (args[0])); + m.Run(); + } +} + +[StructLayout (LayoutKind.Sequential)] +struct mpz_t { + public int _mp_alloc; + public int _mp_size; + public IntPtr ptr; +} + +class GmpInteger { + + // Public methods + + public GmpInteger() { + mpz_init(ref pointer); + } + + public GmpInteger(int value) { + mpz_set_si(ref pointer, value); + } + + public void set(int value) { mpz_set_si(ref pointer, value); } + + public void mul(GmpInteger src, int val) { mpz_mul_si(ref pointer, ref src.pointer, val); } + + public void add(GmpInteger op1, GmpInteger op2) { mpz_add(ref pointer, ref op1.pointer, ref op2.pointer); } + + public void div(GmpInteger op1, GmpInteger op2) { mpz_tdiv_q(ref pointer, ref op1.pointer, ref op2.pointer); } + + public int intValue() { return mpz_get_si(ref pointer); } + + public double doubleValue() { return mpz_get_d(ref pointer); } + + // Non public stuff + + mpz_t pointer; + + [DllImport ("gmp", EntryPoint="__gmpz_init")] + extern static void mpz_init(ref mpz_t value); + + [DllImport ("gmp", EntryPoint="__gmpz_mul_si")] + extern static void mpz_mul_si(ref mpz_t dest, ref mpz_t src, int val); + + [DllImport ("gmp", EntryPoint="__gmpz_add")] + extern static void mpz_add(ref mpz_t dest, ref mpz_t src, ref mpz_t src2); + + [DllImport ("gmp", EntryPoint="__gmpz_tdiv_q")] + extern static void mpz_tdiv_q(ref mpz_t dest, ref mpz_t src, ref mpz_t src2); + + [DllImport ("gmp", EntryPoint="__gmpz_set_si")] + extern static void mpz_set_si(ref mpz_t src, int value); + + [DllImport ("gmp", EntryPoint="__gmpz_get_si")] + extern static int mpz_get_si(ref mpz_t src); + + [DllImport ("gmp", EntryPoint="__gmpz_get_d")] + extern static double mpz_get_d(ref mpz_t src); +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pidigits-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pidigits-serial.cs new file mode 100644 index 0000000000..6d7970df3f --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pidigits-serial.cs @@ -0,0 +1,2 @@ +// best is serial + diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-best.cs new file mode 100644 index 0000000000..b945bc31b2 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-best.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from regex-redux C# .NET Core #5 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=regexredux&lang=csharpcore&id=5 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + Regex-Redux by Josh Goldfoot + order variants by execution time by Anthony Lloyd +*/ + +using System; +using System.Threading.Tasks; +using System.Text.RegularExpressions; + +public static class regexredux +{ + static Regex regex(string re) + { + // Not compiled on .Net Core, hence poor benchmark results. + return new Regex(re, RegexOptions.Compiled); + } + + static string regexCount(string s, string r) + { + int c = 0; + var m = regex(r).Match(s); + while(m.Success) { c++; m = m.NextMatch(); } + return r + " " + c; + } + + public static void Main(string[] args) + { + var sequences = Console.In.ReadToEnd(); + var initialLength = sequences.Length; + sequences = Regex.Replace(sequences, ">.*\n|\n", ""); + + var magicTask = Task.Run(() => + { + var newseq = regex("tHa[Nt]").Replace(sequences, "<4>"); + newseq = regex("aND|caN|Ha[DS]|WaS").Replace(newseq, "<3>"); + newseq = regex("a[NSt]|BY").Replace(newseq, "<2>"); + newseq = regex("<[^>]*>").Replace(newseq, "|"); + newseq = regex("\\|[^|][^|]*\\|").Replace(newseq, "-"); + return newseq.Length; + }); + + var variant2 = Task.Run(() => regexCount(sequences, "[cgt]gggtaaa|tttaccc[acg]")); + var variant3 = Task.Run(() => regexCount(sequences, "a[act]ggtaaa|tttacc[agt]t")); + var variant7 = Task.Run(() => regexCount(sequences, "agggt[cgt]aa|tt[acg]accct")); + var variant6 = Task.Run(() => regexCount(sequences, "aggg[acg]aaa|ttt[cgt]ccct")); + var variant4 = Task.Run(() => regexCount(sequences, "ag[act]gtaaa|tttac[agt]ct")); + var variant5 = Task.Run(() => regexCount(sequences, "agg[act]taaa|ttta[agt]cct")); + var variant1 = Task.Run(() => regexCount(sequences, "agggtaaa|tttaccct")); + var variant9 = Task.Run(() => regexCount(sequences, "agggtaa[cgt]|[acg]ttaccct")); + var variant8 = Task.Run(() => regexCount(sequences, "agggta[cgt]a|t[acg]taccct")); + + Console.Out.WriteLineAsync(variant1.Result); + Console.Out.WriteLineAsync(variant2.Result); + Console.Out.WriteLineAsync(variant3.Result); + Console.Out.WriteLineAsync(variant4.Result); + Console.Out.WriteLineAsync(variant5.Result); + Console.Out.WriteLineAsync(variant6.Result); + Console.Out.WriteLineAsync(variant7.Result); + Console.Out.WriteLineAsync(variant8.Result); + Console.Out.WriteLineAsync(variant9.Result); + Console.Out.WriteLineAsync("\n"+initialLength+"\n"+sequences.Length); + Console.Out.WriteLineAsync(magicTask.Result.ToString()); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-serial.cs new file mode 100644 index 0000000000..12a44b8e29 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regex-redux/regex-redux-serial.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from regex-redux C# .NET Core program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=regexredux&lang=csharpcore&id=1 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + * + * regex-dna program contributed by Isaac Gouy + * converted from regex-dna program + * +*/ + +using System; +using System.Text.RegularExpressions; + +class regexredux +{ + static void Main(string[] args){ + + // read FASTA sequence + String sequence = Console.In.ReadToEnd(); + int initialLength = sequence.Length; + + // remove FASTA sequence descriptions and new-lines + Regex r = new Regex(">.*\n|\n", RegexOptions.Compiled); + sequence = r.Replace(sequence,""); + int codeLength = sequence.Length; + + + // regex match + string[] variants = { + "agggtaaa|tttaccct" + ,"[cgt]gggtaaa|tttaccc[acg]" + ,"a[act]ggtaaa|tttacc[agt]t" + ,"ag[act]gtaaa|tttac[agt]ct" + ,"agg[act]taaa|ttta[agt]cct" + ,"aggg[acg]aaa|ttt[cgt]ccct" + ,"agggt[cgt]aa|tt[acg]accct" + ,"agggta[cgt]a|t[acg]taccct" + ,"agggtaa[cgt]|[acg]ttaccct" + }; + + int count; + foreach (string v in variants){ + count = 0; + r = new Regex(v, RegexOptions.Compiled); + + for (Match m = r.Match(sequence); m.Success; m = m.NextMatch()) count++; + Console.WriteLine("{0} {1}", v, count); + } + + + // regex substitution + IUB[] codes = { + new IUB("tHa[Nt]", "<4>") + ,new IUB("aND|caN|Ha[DS]|WaS", "<3>") + ,new IUB("a[NSt]|BY", "<2>") + ,new IUB("<[^>]*>", "|") + ,new IUB("\\|[^|][^|]*\\|" , "-") + }; + + foreach (IUB iub in codes) { + r = new Regex(iub.code, RegexOptions.Compiled); + sequence = r.Replace(sequence,iub.alternatives); + } + Console.WriteLine("\n{0}\n{1}\n{2}", + initialLength, codeLength, sequence.Length); + } + + + struct IUB + { + public string code; + public string alternatives; + + public IUB(string code, string alternatives) { + this.code = code; + this.alternatives = alternatives; + } + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regexdna/regexdna-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regexdna/regexdna-best.cs new file mode 100644 index 0000000000..d261a0d286 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/regexdna/regexdna-best.cs @@ -0,0 +1 @@ +// no longer up on site diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp-input25.txt b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp-input25.txt index f749b06ea7..f749b06ea7 100644 --- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp-input25.txt +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp-input25.txt diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp-input25000.txt b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp-input25000.txt index fd4414b176..fd4414b176 100644 --- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp-input25000.txt +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp-input25000.txt diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp.csharp-1.cs index bca63bd00e..bca63bd00e 100644 --- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp.csharp-1.cs diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-best.cs new file mode 100644 index 0000000000..8cd35688ac --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-best.cs @@ -0,0 +1,217 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from reverse-complement C# .NET Core #6 +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=csharpcore&id=6 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + Contributed by Peperud + Modified to reduce memory use by Anthony Lloyd +*/ + +using System; +using System.IO; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Threading; + +class RevCompSequence { public List<byte[]> Pages; public int StartHeader, EndExclusive; public Thread ReverseThread; } + +public static class revcomp +{ + const int READER_BUFFER_SIZE = 1024 * 1024; + const byte LF = 10, GT = (byte)'>', SP = 32; + static BlockingCollection<byte[]> readQue = new BlockingCollection<byte[]>(); + static BlockingCollection<RevCompSequence> writeQue = new BlockingCollection<RevCompSequence>(); + static byte[] map; + + static int read(Stream stream, byte[] buffer, int offset, int count) + { + var bytesRead = stream.Read(buffer, offset, count); + return bytesRead==count ? offset+count + : bytesRead==0 ? offset + : read(stream, buffer, offset+bytesRead, count-bytesRead); + } + static void Reader() + { + using (var stream = Console.OpenStandardInput()) + { + int bytesRead; + do + { + var buffer = new byte[READER_BUFFER_SIZE]; + bytesRead = read(stream, buffer, 0, READER_BUFFER_SIZE); + readQue.Add(buffer); + } while(bytesRead==READER_BUFFER_SIZE); + readQue.CompleteAdding(); + } + } + + static bool tryTake<T>(BlockingCollection<T> q, out T t) where T : class + { + t = null; + while(!q.IsCompleted && !q.TryTake(out t)) Thread.SpinWait(0); + return t!=null; + } + + static void Grouper() + { + // Set up complements map + map = new byte[256]; + for (byte b=0; b<255; b++) map[b]=b; + map[(byte)'A'] = (byte)'T'; + map[(byte)'B'] = (byte)'V'; + map[(byte)'C'] = (byte)'G'; + map[(byte)'D'] = (byte)'H'; + map[(byte)'G'] = (byte)'C'; + map[(byte)'H'] = (byte)'D'; + map[(byte)'K'] = (byte)'M'; + map[(byte)'M'] = (byte)'K'; + map[(byte)'R'] = (byte)'Y'; + map[(byte)'T'] = (byte)'A'; + map[(byte)'V'] = (byte)'B'; + map[(byte)'Y'] = (byte)'R'; + map[(byte)'a'] = (byte)'T'; + map[(byte)'b'] = (byte)'V'; + map[(byte)'c'] = (byte)'G'; + map[(byte)'d'] = (byte)'H'; + map[(byte)'g'] = (byte)'C'; + map[(byte)'h'] = (byte)'D'; + map[(byte)'k'] = (byte)'M'; + map[(byte)'m'] = (byte)'K'; + map[(byte)'r'] = (byte)'Y'; + map[(byte)'t'] = (byte)'A'; + map[(byte)'v'] = (byte)'B'; + map[(byte)'y'] = (byte)'R'; + + var startHeader = 0; + var i = 0; + bool afterFirst = false; + var data = new List<byte[]>(); + byte[] bytes; + while (tryTake(readQue, out bytes)) + { + data.Add(bytes); + while((i=Array.IndexOf<byte>(bytes, GT, i+1))!=-1) + { + var sequence = new RevCompSequence { Pages = data + , StartHeader = startHeader, EndExclusive = i }; + if(afterFirst) + (sequence.ReverseThread = new Thread(() => Reverse(sequence))).Start(); + else + afterFirst = true; + writeQue.Add(sequence); + startHeader = i; + data = new List<byte[]> { bytes }; + } + } + i = Array.IndexOf<byte>(data[data.Count-1],0,0); + var lastSequence = new RevCompSequence { Pages = data + , StartHeader = startHeader, EndExclusive = i==-1 ? data[data.Count-1].Length : i }; + Reverse(lastSequence); + writeQue.Add(lastSequence); + writeQue.CompleteAdding(); + } + + static void Reverse(RevCompSequence sequence) + { + var startPageId = 0; + var startBytes = sequence.Pages[0]; + var startIndex = sequence.StartHeader; + + // Skip header line + while((startIndex=Array.IndexOf<byte>(startBytes, LF, startIndex))==-1) + { + startBytes = sequence.Pages[++startPageId]; + startIndex = 0; + } + + var endPageId = sequence.Pages.Count - 1; + var endIndex = sequence.EndExclusive - 1; + if(endIndex==-1) endIndex = sequence.Pages[--endPageId].Length-1; + var endBytes = sequence.Pages[endPageId]; + + // Swap in place across pages + do + { + var startByte = startBytes[startIndex]; + if(startByte<SP) + { + if (++startIndex == startBytes.Length) + { + startBytes = sequence.Pages[++startPageId]; + startIndex = 0; + } + if (startIndex == endIndex && startPageId == endPageId) break; + startByte = startBytes[startIndex]; + } + var endByte = endBytes[endIndex]; + if(endByte<SP) + { + if (--endIndex == -1) + { + endBytes = sequence.Pages[--endPageId]; + endIndex = endBytes.Length - 1; + } + if (startIndex == endIndex && startPageId == endPageId) break; + endByte = endBytes[endIndex]; + } + + startBytes[startIndex] = map[endByte]; + endBytes[endIndex] = map[startByte]; + + if (++startIndex == startBytes.Length) + { + startBytes = sequence.Pages[++startPageId]; + startIndex = 0; + } + if (--endIndex == -1) + { + endBytes = sequence.Pages[--endPageId]; + endIndex = endBytes.Length - 1; + } + } while (startPageId < endPageId || (startPageId == endPageId && startIndex < endIndex)); + if (startIndex == endIndex) startBytes[startIndex] = map[startBytes[startIndex]]; + } + + static void Writer() + { + using (var stream = Console.OpenStandardOutput()) + { + bool first = true; + RevCompSequence sequence; + while (tryTake(writeQue, out sequence)) + { + var startIndex = sequence.StartHeader; + var pages = sequence.Pages; + if(first) + { + Reverse(sequence); + first = false; + } + else + { + sequence.ReverseThread?.Join(); + } + for (int i = 0; i < pages.Count - 1; i++) + { + var bytes = pages[i]; + stream.Write(bytes, startIndex, bytes.Length - startIndex); + startIndex = 0; + } + stream.Write(pages[pages.Count-1], startIndex, sequence.EndExclusive - startIndex); + } + } + } + + public static void Main(string[] args) + { + new Thread(Reader).Start(); + new Thread(Grouper).Start(); + Writer(); + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-serial.cs new file mode 100644 index 0000000000..5838e2f92b --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement-serial.cs @@ -0,0 +1,108 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from reverse-complement C# .NET Core program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=csharpcore&id=1 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Robert F. Tobler to process large blocks of byte arrays +*/ + +using System; +using System.IO; +using System.Collections.Generic; + +static class revcomp +{ + struct Block { + public byte[] Data; public int Count; + public int Read(BinaryReader r) { + Data = r.ReadBytes(16384); Count++; return Data.Length; + } + public Index IndexOf(byte b, int o) { + return new Index { Block = Count, Pos = Array.IndexOf(Data, b, o) }; + } + } + + struct Index { + public int Block; public int Pos; + public static readonly Index None = new Index { Block = -1, Pos = -1 }; + public bool InBlock(Block b) { return Block == b.Count; } + } + + const byte Gt = (byte)'>'; + const byte Lf = (byte)'\n'; + + static void Main(string[] args) { + InitComplements(); + var seq = new List<byte[]>(); + var b = new Block { Count = -1 }; + Index line = Index.None, start = Index.None, end = Index.None; + using (var r = new BinaryReader(Console.OpenStandardInput())) { + using (var w = Console.OpenStandardOutput()) { + while (b.Read(r) > 0) { + seq.Add(b.Data); + if (line.Pos < 0) line = b.IndexOf(Gt, 0); + while (line.Pos >= 0) { + if (start.Pos < 0) { + var off = line.InBlock(b) ? line.Pos : 0; + start = b.IndexOf(Lf, off); + if (start.Pos < 0) { + w.Write(b.Data, off, b.Data.Length - off); + seq.Clear(); break; + } + w.Write(b.Data, off, start.Pos + 1 - off); + } + if (end.Pos < 0) { + end = b.IndexOf(Gt, start.InBlock(b) ? start.Pos : 0); + if (end.Pos < 0) break; + } + w.Reverse(start.Pos, end.Pos, seq); + if (seq.Count > 1) seq.RemoveRange(0, seq.Count - 1); + line = end; end = Index.None; start = Index.None; + } + } + if (start.Pos >= 0 && end.Pos < 0) + w.Reverse(start.Pos, seq[seq.Count -1].Length, seq); + } + } + } + + const string Seq = "ABCDGHKMRTVYabcdghkmrtvy"; + const string Rev = "TVGHCDMKYABRTVGHCDMKYABR"; + static byte[] comp = new byte[256]; + + static void InitComplements() { + for (byte i = 0; i < 255; i++) comp[i] = i; + for (int i = 0; i < Seq.Length; i++) + comp[(byte)Seq[i]] = (byte)Rev[i]; + comp[Lf] = 0; comp[(byte)' '] = 0; + } + + const int LineLen = 61; + const int BufSize = LineLen * 269; + static byte[] buf = new byte[BufSize]; + + static void Reverse(this Stream w, int si, int ei, List<byte[]> bl) { + int bi = 0, line = LineLen - 1; + for (int ri = bl.Count-1; ri >= 0; ri--) { + var b = bl[ri]; int off = ri == 0 ? si : 0; + for (int i = (ri == bl.Count-1 ? ei : b.Length)-1; i >= off; i--) { + var c = comp[b[i]]; if (c > 0) buf[bi++] = c; + if (bi == line) { + buf[bi++] = Lf; line += LineLen; + if (bi == BufSize) { + w.Write(buf, 0, BufSize); bi = 0; line = LineLen - 1; + } + } + } + } + if (bi > 0) { + if (buf[bi-1] != Lf) buf[bi++] = Lf; w.Write(buf, 0, bi); + } + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csproj b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement.csproj index 00789ed3a5..00789ed3a5 100644 --- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csproj +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/reverse-complement.csproj diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm-best.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm-best.cs new file mode 100644 index 0000000000..c82f002147 --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm-best.cs @@ -0,0 +1,153 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from spectral-norm C# .NET Core #3 program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=spectralnorm&lang=csharpcore&id=3 +// Best-scoring C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Isaac Gouy + modified by Josh Goldfoot, based on the Java version by The Anh Tran +*/ + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SpectralNorms +{ + class SpectralNorm + { + public static void Main(String[] args) + { + int n = 100; + if (args.Length > 0) n = Int32.Parse(args[0]); + + Console.WriteLine("{0:f9}", spectralnormGame(n)); + } + + private static double spectralnormGame(int n) + { + double[] u = new double[n]; + double[] v = new double[n]; + double[] tmp = new double[n]; + + // create unit vector + for (int i = 0; i < n; i++) + u[i] = 1.0; + + int nthread = Environment.ProcessorCount; + int chunk = n / nthread; + var barrier = new Barrier(nthread); + Approximate[] ap = new Approximate[nthread]; + + for (int i = 0; i < nthread; i++) + { + int r1 = i * chunk; + int r2 = (i < (nthread - 1)) ? r1 + chunk : n; + ap[i] = new Approximate(u, v, tmp, r1, r2, barrier); + } + + double vBv = 0, vv = 0; + for (int i = 0; i < nthread; i++) + { + ap[i].t.Wait(); + vBv += ap[i].m_vBv; + vv += ap[i].m_vv; + } + + return Math.Sqrt(vBv / vv); + } + + } + + public class Approximate + { + private Barrier barrier; + public Task t; + + private double[] _u; + private double[] _v; + private double[] _tmp; + + private int range_begin, range_end; + public double m_vBv, m_vv; + + public Approximate(double[] u, double[] v, double[] tmp, int rbegin, int rend, Barrier b) + { + m_vBv = 0; + m_vv = 0; + _u = u; + _v = v; + _tmp = tmp; + range_begin = rbegin; + range_end = rend; + barrier = b; + t = Task.Run(() => run()); + } + + private void run() + { + // 20 steps of the power method + for (int i = 0; i < 10; i++) + { + MultiplyAtAv(_u, _tmp, _v); + MultiplyAtAv(_v, _tmp, _u); + } + + for (int i = range_begin; i < range_end; i++) + { + m_vBv += _u[i] * _v[i]; + m_vv += _v[i] * _v[i]; + } + } + + /* return element i,j of infinite matrix A */ + private double eval_A(int i, int j) + { + return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1); + } + + /* multiply vector v by matrix A, each thread evaluate its range only */ + private void MultiplyAv(double[] v, double[] Av) + { + for (int i = range_begin; i < range_end; i++) + { + double sum = 0; + for (int j = 0; j < v.Length; j++) + sum += eval_A(i, j) * v[j]; + + Av[i] = sum; + } + } + + /* multiply vector v by matrix A transposed */ + private void MultiplyAtv(double[] v, double[] Atv) + { + for (int i = range_begin; i < range_end; i++) + { + double sum = 0; + for (int j = 0; j < v.Length; j++) + sum += eval_A(j, i) * v[j]; + + Atv[i] = sum; + } + } + + /* multiply vector v by matrix A and then by matrix A transposed */ + private void MultiplyAtAv(double[] v, double[] tmp, double[] AtAv) + { + + MultiplyAv(v, tmp); + // all thread must syn at completion + barrier.SignalAndWait(); + MultiplyAtv(tmp, AtAv); + // all thread must syn at completion + barrier.SignalAndWait(); + } + + } +} diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm-serial.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm-serial.cs new file mode 100644 index 0000000000..4ea25857ee --- /dev/null +++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm-serial.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Adapted from spectral-norm C# .NET Core program +// http://benchmarksgame.alioth.debian.org/u64q/program.php?test=spectralnorm&lang=csharpcore&id=1 +// Best-scoring single-threaded C# .NET Core version as of 2017-09-01 + +/* The Computer Language Benchmarks Game + http://benchmarksgame.alioth.debian.org/ + + contributed by Isaac Gouy +*/ + +using System; + +class SpectralNorm +{ + public static void Main(String[] args) { + int n = 100; + if (args.Length > 0) n = Int32.Parse(args[0]); + + Console.WriteLine("{0:f9}", new SpectralNorm().Approximate(n)); + } + + double Approximate(int n) { + // create unit vector + double[] u = new double[n]; + for (int i=0; i<n; i++) u[i] = 1; + + // 20 steps of the power method + double[] v = new double[n]; + for (int i=0; i<n; i++) v[i] = 0; + + for (int i=0; i<10; i++) { + MultiplyAtAv(n,u,v); + MultiplyAtAv(n,v,u); + } + + // B=AtA A multiplied by A transposed + // v.Bv /(v.v) eigenvalue of v + double vBv = 0, vv = 0; + for (int i=0; i<n; i++) { + vBv += u[i]*v[i]; + vv += v[i]*v[i]; + } + + return Math.Sqrt(vBv/vv); + } + + + /* return element i,j of infinite matrix A */ + double A(int i, int j){ + return 1.0/((i+j)*(i+j+1)/2 +i+1); + } + + /* multiply vector v by matrix A */ + void MultiplyAv(int n, double[] v, double[] Av){ + for (int i=0; i<n; i++){ + Av[i] = 0; + for (int j=0; j<n; j++) Av[i] += A(i,j)*v[j]; + } + } + + /* multiply vector v by matrix A transposed */ + void MultiplyAtv(int n, double[] v, double[] Atv){ + for (int i=0;i<n;i++){ + Atv[i] = 0; + for (int j=0; j<n; j++) Atv[i] += A(j,i)*v[j]; + } + } + + /* multiply vector v by matrix A and then by matrix A transposed */ + void MultiplyAtAv(int n, double[] v, double[] AtAv){ + double[] u = new double[n]; + MultiplyAv(n,v,u); + MultiplyAtv(n,u,AtAv); + } +} |