--- /dev/null
+// 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.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+namespace FractalPerf
+{
+ struct complex
+ {
+ public complex(double a, double b) { r = a; i = b; }
+ public double r;
+ public double i;
+
+ public complex square() {
+ return new complex(r * r - i * i, 2.0 * r * i);
+ }
+
+ public double sqabs() {
+ return r * r + i * i;
+ }
+
+ public override string ToString() {
+ return String.Format("[{0} + {1}i]", r, i);
+ }
+
+ public static complex operator +(complex a, complex b) {
+ return new complex(a.r + b.r, a.i + b.i);
+ }
+ }
+
+ public abstract class Fractal
+ {
+ protected double XB, YB, XE, YE, XS, YS;
+ const double resolution = 375.0;
+
+ public Fractal(double xbeg, double ybeg, double xend, double yend) {
+ XB = Math.Min(xbeg, xend);
+ YB = Math.Min(ybeg, yend);
+ XE = Math.Max(xbeg, xend);
+ YE = Math.Max(ybeg, yend);
+ XS = (xend - xbeg) / resolution;
+ YS = (yend - ybeg) / resolution;
+ }
+
+ public abstract double Render();
+
+ public static double Clamp(double val, double lo, double hi) {
+ return Math.Min(Math.Max(val, lo), hi);
+ }
+ }
+
+ public class Mandelbrot : Fractal
+ {
+ public Mandelbrot() : base(-2.0, -1.5, 1.0, 1.5) { }
+
+ public override double Render() {
+ double limit = 4.0;
+ double result = 0.0;
+
+ for (double y = YB; y < YE; y += YS) {
+ for (double x = YB; x < YE; x += XS) {
+ complex num = new complex(x, y);
+ complex accum = num;
+ int iters;
+ for (iters = 0; iters < 1000; iters++) {
+ accum = accum.square();
+ accum += num;
+ if (accum.sqabs() > limit)
+ break;
+ }
+ result += iters;
+ }
+ }
+ return result;
+ }
+ }
+
+ public class Julia : Fractal
+ {
+ private double Real;
+ double Imaginary;
+ public Julia(double real, double imaginary)
+ : base(-2.0, -1.5, 1.0, 1.5) {
+ Real = real;
+ Imaginary = imaginary;
+ }
+
+ public override double Render() {
+ double limit = 4.0;
+ double result = 0.0;
+
+ // set the Julia Set constant
+ complex seed = new complex(Real, Imaginary);
+ // run through every point on the screen, setting
+ // m and n to the coordinates
+ for (double m = XB; m < XE; m += XS) {
+ for (double n = YB; n < YE; n += YS) {
+ // the initial z value is the current pixel,
+ // so x and y have to be set to m and n
+ complex accum = new complex(m, n);
+ // perform the iteration
+ int num;
+ for (num = 0; num < 1000; num++) {
+ // exit the loop if the number becomes too big
+ if (accum.sqabs() > limit)
+ break;
+ // use the formula
+ accum = accum.square() + seed;
+ }
+ // determine the color using the number of
+ // iterations it took for the number to become too big
+ // char color = num % number_of_colors;
+ // plot the point
+ result += num;
+ }
+ }
+ return result;
+ }
+ }
+
+ public class Launch
+ {
+
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 5;
+#endif
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static bool Bench()
+ {
+ Mandelbrot m = new Mandelbrot();
+ Julia j = new Julia(-0.62, 0.41);
+ double mResult = m.Render();
+ double jResult = j.Render();
+
+ return true;
+ }
+
+ [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);
+ }
+ }
+}
--- /dev/null
+<?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="FractalPerf.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>