summaryrefslogtreecommitdiff
path: root/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs')
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs250
1 files changed, 250 insertions, 0 deletions
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs
new file mode 100644
index 0000000000..4e875742e8
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/revcomp/revcomp.csharp-1.cs
@@ -0,0 +1,250 @@
+// 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.
+/* The Computer Language Benchmarks Game
+ http://benchmarksgame.alioth.debian.org/
+
+ contributed by Robert F. Tobler to process large blocks of byte arrays
+
+ modified for use with xunit-performance
+*/
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+namespace BenchmarksGame
+{
+
+public static class Revcomp
+{
+
+#if DEBUG
+ const int Iterations = 1;
+ const string InputFile = "revcomp-input25.txt";
+#else
+ const int Iterations = 800;
+ const string InputFile = "revcomp-input25000.txt";
+#endif
+
+ 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 string FindInput(string s)
+ {
+ string CoreRoot = System.Environment.GetEnvironmentVariable("CORE_ROOT");
+
+ if (CoreRoot == null)
+ {
+ Console.WriteLine("This benchmark requries CORE_ROOT to be set");
+ return null;
+ }
+
+ string inputFile = s ?? InputFile;
+
+ // Normal testing -- input file will end up next to the assembly
+ // and CoreRoot points at the test overlay dir
+ string[] pathPartsNormal = new string[] {
+ CoreRoot, "..", "..", "JIT", "Performance",
+ "CodeQuality", "BenchmarksGame", "revcomp", "revcomp", inputFile
+ };
+
+ string inputPathNormal = Path.Combine(pathPartsNormal);
+
+ // Perf testing -- input file will end up next to the assembly
+ // and CoreRoot points at this directory
+ string[] pathPartsPerf = new string[] { CoreRoot, inputFile };
+
+ string inputPathPerf = Path.Combine(pathPartsPerf);
+
+ string inputPath = null;
+
+ if (File.Exists(inputPathNormal))
+ {
+ inputPath = inputPathNormal;
+ }
+ else if (File.Exists(inputPathPerf))
+ {
+ inputPath = inputPathPerf;
+ }
+
+ if (inputPath != null)
+ {
+ Console.WriteLine("Using input file {0}", inputPath);
+ }
+ else
+ {
+ Console.WriteLine("Unable to find input file {0}", inputFile);
+ }
+
+ return inputPath;
+ }
+
+ static int Main(string[] args)
+ {
+ bool verbose = false;
+ string inputFile = InputFile;
+ int iterations = Iterations;
+
+ for (int i = 0; i < args.Length; i++)
+ {
+ if (args[i] == "-v")
+ {
+ verbose = true;
+ }
+ if (args[i] == "-i")
+ {
+ i++;
+
+ if (i < args.Length)
+ {
+ Int32.TryParse(args[i], out iterations);
+ }
+ }
+ else
+ {
+ inputFile = args[i];
+ }
+ }
+
+ string fullInputFile = FindInput(inputFile);
+
+ if (fullInputFile == null)
+ {
+ return -1;
+ }
+
+ if (iterations != Iterations)
+ {
+ Console.WriteLine("Running {0} iterations", iterations);
+ }
+
+ // Warmup
+ BenchInner(false, fullInputFile);
+
+ Stopwatch sw = Stopwatch.StartNew();
+ for (int j = 0; j < iterations; j++)
+ {
+ BenchInner(verbose, fullInputFile);
+ }
+ sw.Stop();
+ Console.WriteLine("revcomp [{0} iters]: {1}ms", iterations, sw.ElapsedMilliseconds);
+
+ return 100;
+ }
+
+ static void BenchInner(bool doOutput, string inputFile)
+ {
+ 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(File.OpenRead(inputFile))) {
+ using (var w = doOutput ? Console.OpenStandardOutput() : Stream.Null) {
+ 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);
+ }
+ }
+
+ [Benchmark]
+ public static void Bench()
+ {
+ string inputFile = FindInput(InputFile);
+
+ if (inputFile == null)
+ {
+ throw new Exception("unable to find input");
+ }
+
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ BenchInner(false, inputFile);
+ }
+ }
+ }
+ }
+}
+
+}