Add more integer benchmarks
authorAndy Ayers <andya@microsoft.com>
Thu, 7 Jan 2016 02:31:45 +0000 (18:31 -0800)
committerAndy Ayers <andya@microsoft.com>
Fri, 8 Jan 2016 03:04:28 +0000 (19:04 -0800)
The remainder of our simple integer benchmarks: AddArray2, Array1, BenchE, CSieve, Permutate, Puzzle, and TreeInsert.

14 files changed:
tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.csproj [new file with mode: 0644]

diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs
new file mode 100644 (file)
index 0000000..898fbdd
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class AddArray2
+{
+#if DEBUG
+    public const int Iterations = 1;
+#else
+    public const int Iterations = 50;
+#endif
+
+    private const int Dim = 200;
+
+    private static T[][] AllocArray<T>(int n1, int n2)
+    {
+        T[][] a = new T[n1][];
+        for (int i = 0; i < n1; ++i)
+        {
+            a[i] = new T[n2];
+        }
+        return a;
+    }
+
+    private static
+    void BenchInner1(int[][] a, ref int nn)
+    {
+        int n;
+        int l, m;
+        n = nn;
+        for (int i = 1; i <= n; i++)
+        {
+            for (int j = (i + 1); j <= n; j++)
+            {
+                for (int k = 1; k <= n; k++)
+                {
+                    l = a[i][k];
+                    m = a[j][k];
+                    unchecked
+                    {
+                        a[j][k] = l + m;
+                    }
+                }
+            }
+        }
+    }
+
+    private static
+    void BenchInner2(int[][] a, ref int nn)
+    {
+        int n;
+        int l, m;
+        n = nn;
+        for (int i = 1; i <= n; i++)
+        {
+            for (int j = (i + 1); j <= n; j++)
+            {
+                for (int k = 1; k <= n; k++)
+                {
+                    l = a[k][i];
+                    m = a[k][j];
+                    unchecked
+                    {
+                        a[k][j] = l + m;
+                    }
+                }
+            }
+        }
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private static bool Bench(int[][] a)
+    {
+        int n = Dim;
+        for (int i = 1; i <= n; i++)
+        {
+            for (int j = 1; j <= n; j++)
+            {
+                a[i][j] = i + j;
+            }
+        }
+
+        BenchInner1(a, ref n);
+        n = Dim;
+        BenchInner2(a, ref n);
+
+        return true;
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        int[][] array = AllocArray<int>(Dim + 1, Dim + 1);
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                for (int i = 1; i <= Iterations; i++)
+                {
+                    Bench(array);
+                }
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        int[][] array = AllocArray<int>(Dim + 1, Dim + 1);
+        bool result = true;
+        for (int i = 1; i <= Iterations; i++)
+        {
+            result &= Bench(array);
+        }
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.csproj
new file mode 100644 (file)
index 0000000..c7bd5d3
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AddArray2.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs
new file mode 100644 (file)
index 0000000..d5876cd
--- /dev/null
@@ -0,0 +1,153 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// The sorting benchmark calls a random number generator the number
+// of times specified by Maxnum to create an array of int integers,
+// then does a quicksort on the array of ints. Random numbers
+// are produced using a multiplicative modulus method with known
+// seed, so that the generated array is constant across compilers.
+//
+// This is adapted from a benchmark in BYTE Magazine, August 1984.
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class Array1
+{
+#if DEBUG
+    private const int Iterations = 1;
+    private const int Maxnum = 100;
+#else
+    private const int Iterations = 125;
+    private const int Maxnum = 1000;
+#endif
+
+    private const int Modulus = ((int)0x20000);
+    private const int C = 13849;
+    private const int A = 25173;
+    static int s_seed = 7;
+
+    private static void Quick(int lo, int hi, int[] input)
+    {
+        int i, j;
+        int pivot, temp;
+
+        if (lo < hi)
+        {
+            // 0 <= lo < hi
+            for (i = lo, j = (hi + 1), pivot = input[lo]; ;)
+            {
+                do
+                {
+                    ++i;
+                } while (input[i] < pivot);
+
+                do
+                {
+                    --j;
+                    // Accessing upto hi
+                } while (input[j] > pivot);
+
+                if (i < j)
+                {
+                    temp = input[i];
+                    input[i] = input[j];
+                    input[j] = temp;
+                }
+                else
+                {
+                    break;
+                }
+            }
+            temp = input[j];
+            input[j] = input[lo];
+            input[lo] = temp;
+            Quick(lo, j - 1, input);
+            Quick(j + 1, hi, input);
+        }
+    }
+
+    private static int Random(int size)
+    {
+        unchecked
+        {
+            s_seed = s_seed * A + C;
+        }
+
+        return (s_seed % size);
+    }
+
+    private static bool VerifySort(int[] buffer)
+    {
+        for (int y = 0; y < Maxnum - 2; y++)
+        {
+            if (buffer[y] > buffer[y + 1])
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private static bool Bench()
+    {
+        int[] buffer = new int[Maxnum + 1];
+
+        for (int i = 0; i < Iterations; ++i)
+        {
+            for (int j = 0; j < Maxnum; ++j)
+            {
+                int temp = Random(Modulus);
+                if (temp < 0L)
+                {
+                    temp = (-temp);
+                }
+                buffer[j] = temp;
+            }
+            buffer[Maxnum] = Modulus;
+
+            Quick(0, Maxnum - 1, buffer);
+        }
+
+        bool result = VerifySort(buffer);
+
+        return result;
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                for (int i = 0; i < Iterations; i++)
+                {
+                    Bench();
+                }
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        bool result = true;
+        for (int i = 0; i < Iterations; i++)
+        {
+            result &= Bench();
+        }
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.csproj
new file mode 100644 (file)
index 0000000..55b9c37
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Array1.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs
new file mode 100644 (file)
index 0000000..f6528f4
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class BenchE
+{
+#if DEBUG
+    public const int Iterations = 1;
+#else
+    public const int Iterations = 5000000;
+#endif
+
+    private static int s_position;
+
+    private static int Strsch(char[] s, char[] k, int ns, int nk)
+    {
+        int i, j;
+        int start, ksave, cont;
+        int kend, ssave;
+        int r;
+
+        start = 0;
+        ksave = 0;
+        cont = ns - nk + start;
+        kend = ksave + nk - 1;
+        i = 0;
+        j = 0;
+    top:
+        while (s[i] != k[j])
+        {
+            // s is accessed upto cont i.e. ns - nk + 0
+            if (i >= cont)
+            {
+                r = -1;
+                goto bottom;
+            }
+            i = i + 1;
+        }
+        ssave = i;
+        j = j + 1;
+        while (j <= kend)
+        {
+            i = i + 1;
+            // j <= kend, so k is accessed upto 0 + nk - 1
+            if (s[i] != k[j])
+            {
+                i = ssave + 1;
+                j = ksave;
+                goto top;
+            }
+            j = j + 1;
+        }
+        r = ssave - start + 1;
+    bottom:
+        return r;
+    }
+
+    private static void BenchInner(char[] s, char[] k)
+    {
+        int ns, nk;
+
+        ns = 120;
+        nk = 15;
+        s_position = Strsch(s, k, ns, nk);
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private static bool Bench()
+    {
+        char[] s = {
+            '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'H', 'E', 'R', 'E', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+            'H', 'E', 'R', 'E', ' ', 'I', 'S', ' ', 'A', ' ', 'M', 'A', 'T', 'C', 'H', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'
+        };
+
+        char[] k = { 'H', 'E', 'R', 'E', ' ', 'I', 'S', ' ', 'A', ' ', 'M', 'A', 'T', 'C', 'H', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
+
+        for (int i = 0; i < Iterations; i++)
+        {
+            BenchInner(s, k);
+        }
+
+        return (s_position == 91);
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                Bench();
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        bool result = Bench();
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.csproj
new file mode 100644 (file)
index 0000000..1eb9bd7
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BenchE.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs
new file mode 100644 (file)
index 0000000..8961d31
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// Based on Eratosthenes Sieve Prime Number Program in C, Byte Magazine, January 1983.
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class CSieve
+{
+
+#if DEBUG
+    public const int Iterations = 1;
+#else
+    public const int Iterations = 200;
+#endif
+
+    const int Size = 8190;
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    static bool Bench() {
+        bool[] flags = new bool[Size + 1];
+        int count = 0;
+        for (int iter = 1; iter <= Iterations; iter++)
+        {
+            count = 0;
+
+            // Initially, assume all are prime
+            for (int i = 0; i <= Size; i++)
+            {
+                flags[i] = true;
+            }
+
+            // Refine
+            for (int i = 2; i <= Size; i++)
+            {
+                if (flags[i])
+                {
+                    // Found a prime
+                    for (int k = i + i; k <= Size; k += i)
+                    {
+                        // Cancel its multiples
+                        flags[k] = false;
+                    }
+                    count++;
+                }
+            }
+        }
+
+        return (count == 1027);
+    }
+
+    [Benchmark]
+    public static void Test() {
+        foreach (var iteration in Benchmark.Iterations) {
+            using (iteration.StartMeasurement()) {
+                for (int i = 0; i < Iterations; i++) {
+                    Bench();
+                }
+            }
+        }
+    }
+
+    static bool TestBase() {
+        bool result = true;
+        for (int i = 0; i < Iterations; i++) {
+            result &= Bench();
+        }
+        return result;
+    }
+    
+    public static int Main() {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.csproj
new file mode 100644 (file)
index 0000000..cd8ba12
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CSieve.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs
new file mode 100644 (file)
index 0000000..63c2c7d
--- /dev/null
@@ -0,0 +1,115 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public class Permutate
+{
+#if DEBUG
+    public const int Iterations = 1;
+#else
+    public const int Iterations = 20000;
+#endif
+
+    private int[] _permArray = new int[11];
+    private static int s_pctr;
+
+    private static
+    void Swap(int[] arr, int i, int j)
+    {
+        int t = arr[i];
+        arr[i] = arr[j];
+        arr[j] = t;
+    }
+
+    private void Initialize()
+    {
+        for (int i = 1; i <= 7; i++)
+        {
+            _permArray[i] = i - 1;
+        }
+    }
+
+    private void PermuteArray(int n)
+    {
+        int k;
+        s_pctr = s_pctr + 1;
+        if (n != 1)
+        {
+            PermuteArray(n - 1);
+            for (k = n - 1; k >= 1; k--)
+            {
+                Swap(_permArray, n, k);
+                PermuteArray(n - 1);
+                Swap(_permArray, n, k);
+            }
+        }
+    }
+
+    private bool Validate()
+    {
+        int k = 0;
+
+        for (int i = 0; i <= 6; i++)
+        {
+            for (int j = 1; j <= 7; j++)
+            {
+                if (_permArray[j] == i)
+                {
+                    k = k + 1;
+                }
+            }
+        }
+
+        return (k == 7);
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private bool Bench()
+    {
+        Initialize();
+
+        for (int i = 0; i < Iterations; ++i)
+        {
+            s_pctr = 0;
+            PermuteArray(7);
+        }
+
+        bool result = Validate();
+
+        return result;
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        Permutate P = new Permutate();
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                P.Bench();
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        Permutate P = new Permutate();
+        bool result = P.Bench();
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.csproj
new file mode 100644 (file)
index 0000000..c9046da
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Permutate.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs
new file mode 100644 (file)
index 0000000..44b9e0e
--- /dev/null
@@ -0,0 +1,392 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public class Puzzle
+{
+#if DEBUG
+    public const int Iterations = 1;
+#else
+    public const int Iterations = 400;
+#endif
+
+    private const int PuzzleSize = 511;
+    private const int ClassMax = 3;
+    private const int TypeMax = 12;
+    private const int D = 8;
+
+    private int[] _pieceCount = new int[ClassMax + 1];
+    private int[] _class = new int[TypeMax + 1];
+    private int[] _pieceMax = new int[TypeMax + 1];
+    private bool[] _puzzle = new bool[PuzzleSize + 1];
+    private bool[][] _p;
+    private int _count;
+
+    private static T[][] AllocArray<T>(int n1, int n2)
+    {
+        T[][] a = new T[n1][];
+        for (int i = 0; i < n1; ++i)
+        {
+            a[i] = new T[n2];
+        }
+
+        return a;
+    }
+
+    private bool Fit(int i, int j)
+    {
+        for (int k = 0; k <= _pieceMax[i]; k++)
+        {
+            if (_p[i][k])
+            {
+                if (_puzzle[j + k])
+                {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private int Place(int i, int j)
+    {
+        int k;
+        for (k = 0; k <= _pieceMax[i]; k++)
+        {
+            if (_p[i][k])
+            {
+                _puzzle[j + k] = true;
+            }
+        }
+
+        _pieceCount[_class[i]] = _pieceCount[_class[i]] - 1;
+
+        for (k = j; k <= PuzzleSize; k++)
+        {
+            if (!_puzzle[k])
+            {
+                return k;
+            }
+        }
+
+        return 0;
+    }
+
+    private void RemoveLocal(int i, int j)
+    {
+        for (int k = 0; k <= _pieceMax[i]; k++)
+        {
+            if (_p[i][k])
+            {
+                _puzzle[j + k] = false;
+            }
+        }
+
+        _pieceCount[_class[i]] = _pieceCount[_class[i]] + 1;
+    }
+
+    private bool Trial(int j)
+    {
+        for (int i = 0; i <= TypeMax; i++)
+        {
+            if (_pieceCount[_class[i]] != 0)
+            {
+                if (Fit(i, j))
+                {
+                    int k = Place(i, j);
+                    if (Trial(k) || (k == 0))
+                    {
+                        _count = _count + 1;
+                        return true;
+                    }
+                    else
+                    {
+                        RemoveLocal(i, j);
+                    }
+                }
+            }
+        }
+
+        _count = _count + 1;
+        return false;
+    }
+
+    private bool DoIt()
+    {
+        int i, j, k, m, n;
+
+        for (m = 0; m <= PuzzleSize; m++)
+        {
+            _puzzle[m] = true;
+        }
+
+        for (i = 1; i <= 5; i++)
+        {
+            for (j = 1; j <= 5; j++)
+            {
+                for (k = 1; k <= 5; k++)
+                {
+                    _puzzle[i + D * (j + D * k)] = false;
+                }
+            }
+        }
+
+        for (i = 0; i <= TypeMax; i++)
+        {
+            for (m = 0; m <= PuzzleSize; m++)
+            {
+                _p[i][m] = false;
+            }
+        }
+
+        for (i = 0; i <= 3; i++)
+        {
+            for (j = 0; j <= 1; j++)
+            {
+                for (k = 0; k <= 0; k++)
+                {
+                    _p[0][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[0] = 0;
+        _pieceMax[0] = 3 + D * 1 + D * D * 0;
+
+        for (i = 0; i <= 1; i++)
+        {
+            for (j = 0; j <= 0; j++)
+            {
+                for (k = 0; k <= 3; k++)
+                {
+                    _p[1][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[1] = 0;
+        _pieceMax[1] = 1 + D * 0 + D * D * 3;
+
+        for (i = 0; i <= 0; i++)
+        {
+            for (j = 0; j <= 3; j++)
+            {
+                for (k = 0; k <= 1; k++)
+                {
+                    _p[2][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+        _class[2] = 0;
+        _pieceMax[2] = 0 + D * 3 + D * D * 1;
+
+        for (i = 0; i <= 1; i++)
+        {
+            for (j = 0; j <= 3; j++)
+            {
+                for (k = 0; k <= 0; k++)
+                {
+                    _p[3][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[3] = 0;
+        _pieceMax[3] = 1 + D * 3 + D * D * 0;
+
+        for (i = 0; i <= 3; i++)
+        {
+            for (j = 0; j <= 0; j++)
+            {
+                for (k = 0; k <= 1; k++)
+                {
+                    _p[4][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[4] = 0;
+        _pieceMax[4] = 3 + D * 0 + D * D * 1;
+
+        for (i = 0; i <= 0; i++)
+        {
+            for (j = 0; j <= 1; j++)
+            {
+                for (k = 0; k <= 3; k++)
+                {
+                    _p[5][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[5] = 0;
+        _pieceMax[5] = 0 + D * 1 + D * D * 3;
+
+        for (i = 0; i <= 2; i++)
+        {
+            for (j = 0; j <= 0; j++)
+            {
+                for (k = 0; k <= 0; k++)
+                {
+                    _p[6][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[6] = 1;
+        _pieceMax[6] = 2 + D * 0 + D * D * 0;
+
+        for (i = 0; i <= 0; i++)
+        {
+            for (j = 0; j <= 2; j++)
+            {
+                for (k = 0; k <= 0; k++)
+                {
+                    _p[7][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[7] = 1;
+        _pieceMax[7] = 0 + D * 2 + D * D * 0;
+
+        for (i = 0; i <= 0; i++)
+        {
+            for (j = 0; j <= 0; j++)
+            {
+                for (k = 0; k <= 2; k++)
+                {
+                    _p[8][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[8] = 1;
+        _pieceMax[8] = 0 + D * 0 + D * D * 2;
+
+        for (i = 0; i <= 1; i++)
+        {
+            for (j = 0; j <= 1; j++)
+            {
+                for (k = 0; k <= 0; k++)
+                {
+                    _p[9][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+        _class[9] = 2;
+        _pieceMax[9] = 1 + D * 1 + D * D * 0;
+
+        for (i = 0; i <= 1; i++)
+        {
+            for (j = 0; j <= 0; j++)
+            {
+                for (k = 0; k <= 1; k++)
+                {
+                    _p[10][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[10] = 2;
+        _pieceMax[10] = 1 + D * 0 + D * D * 1;
+
+        for (i = 0; i <= 0; i++)
+        {
+            for (j = 0; j <= 1; j++)
+            {
+                for (k = 0; k <= 1; k++)
+                {
+                    _p[11][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[11] = 2;
+        _pieceMax[11] = 0 + D * 1 + D * D * 1;
+
+        for (i = 0; i <= 1; i++)
+        {
+            for (j = 0; j <= 1; j++)
+            {
+                for (k = 0; k <= 1; k++)
+                {
+                    _p[12][i + D * (j + D * k)] = true;
+                }
+            }
+        }
+
+        _class[12] = 3;
+        _pieceMax[12] = 1 + D * 1 + D * D * 1;
+        _pieceCount[0] = 13;
+        _pieceCount[1] = 3;
+        _pieceCount[2] = 1;
+        _pieceCount[3] = 1;
+        m = 1 + D * (1 + D * 1);
+        _count = 0;
+
+        bool result = true;
+
+        if (Fit(0, m))
+        {
+            n = Place(0, m);
+            result = Trial(n);
+        }
+        else
+        {
+            result = false;
+        }
+
+        return result;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private bool Bench()
+    {
+        _p = AllocArray<bool>(TypeMax + 1, PuzzleSize + 1);
+
+        bool result = true;
+
+        for (int i = 0; i < Iterations; ++i)
+        {
+            result &= DoIt();
+        }
+
+        return result;
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        Puzzle P = new Puzzle();
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                P.Bench();
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        Puzzle P = new Puzzle();
+        bool result = P.Bench();
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.csproj
new file mode 100644 (file)
index 0000000..286eaf7
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Puzzle.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs
new file mode 100644 (file)
index 0000000..c03d5aa
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public class TreeInsert
+{
+#if DEBUG
+    public const int Iterations = 1;
+#else
+    public const int Iterations = 15000;
+#endif
+
+    private struct Node
+    {
+        public int A;
+        public int L;
+        public int R;
+    }
+
+    private struct Tree
+    {
+        public int Root;
+        public int NextAvail;
+        public Node[] Nodes;
+    }
+
+    private Tree _s;
+
+    public TreeInsert()
+    {
+        _s.Nodes = new Node[10001];
+    }
+
+    private void BenchInner(int x)
+    {
+        /* a tree insertion routine from knuth */
+        int i = _s.Root;
+        int j = _s.NextAvail;
+
+    L10:
+        /* compare */
+        if (_s.Nodes[i].A < x)
+        {
+            if (_s.Nodes[i].L != 0)
+            {
+                i = _s.Nodes[i].L;
+                goto L10;
+            }
+            else
+            {
+                _s.Nodes[i].L = j;
+                goto L20;
+            }
+        }
+        else
+        {
+            if (_s.Nodes[i].R != 0)
+            {
+                i = _s.Nodes[i].R;
+                goto L10;
+            }
+            else
+            {
+                _s.Nodes[i].R = j;
+                goto L20;
+            }
+        }
+
+    L20:
+        /* insert */
+        _s.Nodes[j].A = x;
+        _s.Nodes[j].L = 0;
+        _s.Nodes[j].R = 0;
+        _s.NextAvail = j + 1;
+    }
+
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private bool Bench()
+    {
+        _s.Root = 1;
+        _s.NextAvail = 2;
+        _s.Nodes[1].A = 300;
+        _s.Nodes[1].L = 0;
+        _s.Nodes[1].R = 0;
+
+        int j = 99999;
+        for (int i = 1; i <= 900; i++)
+        {
+            BenchInner(j & 4095);
+            j = j + 33333;
+        }
+
+        return (_s.Nodes[500].A == 441);
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        TreeInsert T = new TreeInsert();
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                for (int i = 1; i <= Iterations; i++)
+                {
+                    T.Bench();
+                }
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        TreeInsert T = new TreeInsert();
+        bool result = true;
+        for (int i = 1; i <= Iterations; i++)
+        {
+            result &= T.Bench();
+        }
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.csproj b/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.csproj
new file mode 100644 (file)
index 0000000..42f6d6d
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="$(JitPackagesConfigFileDirectory)benchmark\project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="TreeInsert.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>