summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Provider/PerformanceTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/Performance/CodeTimers.cs94
-rw-r--r--src/DotNetOpenAuth.Test/Performance/HighPerformance.cs69
-rw-r--r--src/DotNetOpenAuth.Test/Performance/PerformanceMeasurement.cs268
-rw-r--r--src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs111
-rw-r--r--src/DotNetOpenAuth.Test/Performance/PowerManagement.cs35
7 files changed, 196 insertions, 385 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index 8c5034c..873cde4 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -305,7 +305,7 @@
<Compile Include="OpenId\UriIdentifierTests.cs" />
<Compile Include="OpenId\XriIdentifierTests.cs" />
<Compile Include="Performance\CodeTimers.cs" />
- <Compile Include="Performance\PerformanceMeasurement.cs" />
+ <Compile Include="Performance\HighPerformance.cs" />
<Compile Include="Performance\PerformanceTestUtilities.cs" />
<Compile Include="Performance\PowerManagement.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
diff --git a/src/DotNetOpenAuth.Test/OpenId/Provider/PerformanceTests.cs b/src/DotNetOpenAuth.Test/OpenId/Provider/PerformanceTests.cs
index fb1125e..d35ac1d 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Provider/PerformanceTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Provider/PerformanceTests.cs
@@ -18,8 +18,8 @@ namespace DotNetOpenAuth.Test.OpenId.Provider {
using DotNetOpenAuth.OpenId.ChannelElements;
using DotNetOpenAuth.OpenId.Messages;
using DotNetOpenAuth.OpenId.Provider;
- using NUnit.Framework;
using DotNetOpenAuth.Test.Performance;
+ using NUnit.Framework;
[TestFixture, Category("Performance")]
public class PerformanceTests : OpenIdTestBase {
diff --git a/src/DotNetOpenAuth.Test/Performance/CodeTimers.cs b/src/DotNetOpenAuth.Test/Performance/CodeTimers.cs
index 78f8766..85fa83d 100644
--- a/src/DotNetOpenAuth.Test/Performance/CodeTimers.cs
+++ b/src/DotNetOpenAuth.Test/Performance/CodeTimers.cs
@@ -1,3 +1,4 @@
+// <auto-generated/> // well, imported. But this gets StyleCop off our back
//-----------------------------------------------------------------------
// <copyright file="CodeTimers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. All rights reserved.
@@ -15,9 +16,20 @@ namespace DotNetOpenAuth.Test.Performance {
/// statistics on this list (Mean, Median, StandardDeviation ...)
/// </summary>
internal class Stats : IEnumerable<float> {
+ private List<float> data;
+ private float minimum;
+ private float maximum;
+ private float median;
+ private float mean;
+ private float standardDeviation;
+ private bool statsComputed;
+
public Stats() { data = new List<float>(); }
- public void Add(float dataItem) { statsComputed = false; data.Add(dataItem); }
+ public void Add(float dataItem) {
+ statsComputed = false;
+ data.Add(dataItem);
+ }
public void RemoveRange(int index, int count) {
data.RemoveRange(index, count);
statsComputed = false;
@@ -37,22 +49,71 @@ namespace DotNetOpenAuth.Test.Performance {
public IEnumerator<float> GetEnumerator() { return data.GetEnumerator(); }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return data.GetEnumerator(); }
- public float Minimum { get { if (!statsComputed) ComputeStats(); return minimum; } }
- public float Maximum { get { if (!statsComputed) ComputeStats(); return maximum; } }
- public float Median { get { if (!statsComputed) ComputeStats(); return median; } }
- public float Mean { get { if (!statsComputed) ComputeStats(); return mean; } }
- public float StandardDeviation { get { if (!statsComputed) ComputeStats(); return standardDeviation; } }
+ public float Minimum {
+ get {
+ if (!statsComputed) {
+ this.ComputeStats();
+ }
+
+ return minimum;
+ }
+ }
+ public float Maximum {
+ get {
+ if (!statsComputed) {
+ this.ComputeStats();
+ }
+
+ return maximum;
+ }
+ }
+ public float Median {
+ get {
+ if (!statsComputed) {
+ this.ComputeStats();
+ }
+
+ return median;
+ }
+ }
+
+ public float Mean {
+ get {
+ if (!statsComputed) {
+ this.ComputeStats();
+ }
+
+ return mean;
+ }
+ }
+
+ public float StandardDeviation {
+ get {
+ if (!statsComputed) {
+ this.ComputeStats();
+ }
+
+ return standardDeviation;
+ }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="System.String"/> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String"/> that represents this instance.
+ /// </returns>
public override string ToString() {
- if (!statsComputed)
+ if (!statsComputed) {
ComputeStats();
+ }
+
return "mean=" + mean.ToString("f3") + " median=" + median.ToString("f3") +
" min=" + minimum.ToString("f3") + " max=" + maximum.ToString("f3") +
" sdtdev=" + standardDeviation.ToString("f3") + " samples=" + Count.ToString();
}
- #region privates
-
- public void ComputeStats() {
+ private void ComputeStats() {
minimum = float.MaxValue;
maximum = float.MinValue;
median = 0.0F;
@@ -86,15 +147,6 @@ namespace DotNetOpenAuth.Test.Performance {
statsComputed = true;
}
-
- List<float> data;
- float minimum;
- float maximum;
- float median;
- float mean;
- float standardDeviation;
- bool statsComputed;
- #endregion
};
/// <summary>
@@ -225,8 +277,8 @@ namespace DotNetOpenAuth.Test.Performance {
// mode so so that we get more stable results.
// TODO: see if this is true, and if there is a better way of doing it.
Stopwatch sw = Stopwatch.StartNew();
- while (sw.ElapsedMilliseconds < 32)
- ;
+ while (sw.ElapsedMilliseconds < 32) {
+ }
}
/// <summary>
/// The number of times the benchmark is run in a loop for a single measument.
diff --git a/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs b/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs
new file mode 100644
index 0000000..32b4cfa
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/Performance/HighPerformance.cs
@@ -0,0 +1,69 @@
+//-----------------------------------------------------------------------
+// <copyright file="HighPerformance.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Performance {
+ using System;
+ using System.Diagnostics;
+ using System.Threading;
+ using log4net;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Suppresses logging and forces the CPU into a high performance mode.
+ /// </summary>
+ internal class HighPerformance : IDisposable {
+ private readonly log4net.Core.Level originalLoggerThreshold;
+ private readonly PowerManagment.PowerSetting powerSetting;
+ private readonly ProcessPriorityClass originalProcessPriority;
+
+#pragma warning disable 0618
+ /// <summary>
+ /// Initializes a new instance of the <see cref="HighPerformance"/> class.
+ /// </summary>
+ internal HighPerformance() {
+ if (!PerformanceTestUtilities.CoolOff()) {
+ Assert.Inconclusive("Timed out waiting for a quiet CPU in which to perform perf tests.");
+ }
+
+ this.originalLoggerThreshold = LogManager.GetLoggerRepository().Threshold;
+ LogManager.GetLoggerRepository().Threshold = LogManager.GetLoggerRepository().LevelMap["OFF"];
+ this.powerSetting = new PowerManagment.PowerSetting(PowerManagment.PowerProfiles.HighPerformance);
+ this.originalProcessPriority = Process.GetCurrentProcess().PriorityClass;
+ Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
+ Thread.CurrentThread.Priority = ThreadPriority.Highest;
+ HighCpu();
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose() {
+ Thread.CurrentThread.Priority = ThreadPriority.Normal;
+ Process.GetCurrentProcess().PriorityClass = this.originalProcessPriority;
+ this.powerSetting.Dispose(); // restores original power setting.
+ LogManager.GetLoggerRepository().Threshold = this.originalLoggerThreshold;
+ }
+#pragma warning restore 0618
+
+ /// <summary>
+ /// Runs the CPU in a tight loop to get it out of any low power state.
+ /// </summary>
+ private static void HighCpu() {
+ int dummy;
+ new MultiSampleCodeTimer(10, 1000).Measure(
+ "Loop 1K times",
+ 1,
+ delegate {
+ int k = 0;
+ while (k < 1000) {
+ k++; // still in danger of being optimized.
+ }
+
+ dummy = k; // avoid optimization.
+ });
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/Performance/PerformanceMeasurement.cs b/src/DotNetOpenAuth.Test/Performance/PerformanceMeasurement.cs
deleted file mode 100644
index 6199005..0000000
--- a/src/DotNetOpenAuth.Test/Performance/PerformanceMeasurement.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-//-----------------------------------------------------------------------
-// <copyright file="CodeTimers.cs" company="Microsoft Corporation">
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// </copyright>
-// <author>Vance Morrison</author>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.Test.Performance {
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO;
- using System.Web; // for HttpUtility.HtmlEncode
- using System.Reflection; // for Assembly
- using System.Diagnostics; // for Process, DebuggableAttribute
-
- /// <summary>
- /// A code:StatsLogger is something that remembers a set of common
- /// atrributes (verison of the code, Machine used, NGENed or JITed ...) as
- /// well as a set of performance results from mulitple benchmarks.
- /// (represented by a code:StatsCollection)
- ///
- /// The primary value of a StatsLogger is the
- /// code:StatsLogger.DisplayHtmlReport which displayes the data in a
- /// user-friendly way.
- /// </summary>
- internal class StatsLogger {
- public StatsLogger(StatsCollection dataSet) {
- this.dataSet = dataSet;
- attributes = new Dictionary<string, object>();
- }
- StatsCollection DataSet { get { return dataSet; } }
- public object this[string key] {
- get { return attributes[key]; }
- set { attributes[key] = value; }
- }
- public void Add(string name, Stats sample) { dataSet.Add(name, sample); }
- public string Category {
- get { return category; }
- set { category = value; }
- }
- public void AddWithCount(string name, int iterationCount, float scale, Stats sample) {
- if (!string.IsNullOrEmpty(category))
- name = category + ": " + name;
- if (iterationCount != 1 || scale != 1) {
- name += " [";
- if (iterationCount != 1) {
- name = name + "count=" + iterationCount.ToString();
- if (scale != 1)
- name += " ";
- }
- if (scale != 1)
- name = name + " scale=" + scale.ToString("f1");
- name += "]";
- }
-
- Add(name, sample);
- }
- public void DisplayHtmlReport(string reportFileName) {
- TextWriter writer = File.CreateText(reportFileName);
-
- writer.WriteLine("<html>");
- writer.WriteLine("<h1> MeasureIt Performance Results </h1>");
- object optimizationValue;
- if (attributes.TryGetValue("CodeOptimization", out optimizationValue) && ((string)optimizationValue) == "Unoptimized") {
- writer.WriteLine("<font color=red><p>");
- writer.WriteLine("Warning: the MeasureIt code was not optimized. The results are likely invalid.");
- writer.WriteLine("</p></font>");
- }
- if (Environment.OSVersion.Version.Major < 6) {
- writer.WriteLine("<b><p>");
- writer.WriteLine("Data was collected on a Pre-Vista machine. MeasureIt does NOT automatically");
- writer.WriteLine("set the CPU to a high performance power policy. This means the CPU might");
- writer.WriteLine("be throttled to save power and can lead to");
- writer.WriteLine("incorrect and inconsistant benchmark measurements.");
- writer.WriteLine("</p></b>");
- } else if (PowerManagment.CurrentPolicy != PowerManagment.PowerProfiles.HighPerformance) {
- writer.WriteLine("<font color=red><p>");
- writer.WriteLine("Warning: The power policy settings were not set at 'High Performance' during this run.");
- writer.WriteLine("This means that the CPU could be throttled to lower frequency resulting in");
- writer.WriteLine("incorrect and inconsistant benchmark measurements.");
- writer.WriteLine("To correct go to Start Menu -> Contol Panel -> System and Maintance -> Power Options");
- writer.WriteLine("and set the power policy to 'High Performance' for the duration of the tests.");
- writer.WriteLine("</p></font>");
- }
- writer.WriteLine("<p>");
- writer.WriteLine("Below are the results of running a series of benchmarks. Use the");
- writer.WriteLine("<b>MeasureIt /usersGuide</b> for more details on exactly what the benchmarks do.");
- writer.WriteLine("</p><p>");
- writer.WriteLine("It is very easy for benchmark results to be wrong or misleading. You should read the guidance");
- writer.WriteLine("in the <b>MeasureIt /usersGuide</b> before making important decisions based on this data.");
- writer.WriteLine("</p><p>");
- writer.WriteLine("To improve the stability of the measurements, a may be cloned several times");
- writer.WriteLine("and this cloned code is then run in a loop.");
- writer.WriteLine("If the benchmark was cloned the 'scale' attribute represents the number of times");
- writer.WriteLine("it was cloned, and the count represents the number of times the cloned code was run in a loop");
- writer.WriteLine("before the measurement was made. The reported number divides by both");
- writer.WriteLine("of these values, so it represents a single instance of the operation being measured.");
- writer.WriteLine("</p>");
- writer.WriteLine("<p>");
- writer.WriteLine("The benchmarks data can vary from run to run, so the benchmark is run several times and");
- writer.WriteLine("the statistics are displayed. If we assume a normal distribution, you can expect 68% of all measureuments");
- writer.WriteLine("to fall within 1 StdDev of the Mean. You can expect over 95% of all measurements");
- writer.WriteLine("to fall witin 2 StdDev of the Mean. Thus 2 StdDev is a good error bound.");
- writer.WriteLine("Keep in mind, however that it is not uncommon for the statistics to be quite stable");
- writer.WriteLine("during a run and yet very widely across different runs. See the users guide for more.");
- writer.WriteLine("</p>");
- writer.WriteLine("<p>");
- writer.WriteLine("Generally the mean is a better measurment if you use the number to compute an");
- writer.WriteLine("aggregate throughput for a large number of items. The median is a better");
- writer.WriteLine("guess if you want to best guess of a typical sample. The median is also");
- writer.WriteLine("more stable if the sample is noisy (eg has outliers).");
- writer.WriteLine("</p>");
- writer.WriteLine("<h3>Data collected</h3>");
- {
- writer.WriteLine("<p>");
- writer.WriteLine(UnitsDescription);
- writer.WriteLine("</p>");
-
- dataSet.WriteReportTable(writer, Scale);
- }
-
- writer.WriteLine("<p>");
- {
- writer.WriteLine("<h2>Attributes of the machine used to collect the data</h2>");
- writer.WriteLine("<table border>");
- writer.WriteLine("<tr><th>Attribute</th><th>Value</th></tr>");
- foreach (string key in attributes.Keys) {
- object valueObj = this[key];
- writer.Write("<tr>");
- writer.Write("<td>" + HttpUtility.HtmlEncode(key) + "</td>");
-
- string valueStr = HttpUtility.HtmlEncode(valueObj.ToString());
- writer.Write("<td>" + valueStr + "</td>");
- writer.WriteLine("<tr>");
- }
- writer.WriteLine("</table>");
- }
- writer.WriteLine("</p>");
-
- writer.WriteLine("</html>");
- writer.Close();
- }
- static public void LaunchIE(string fileName) {
- Process process = new Process();
- process.StartInfo = new ProcessStartInfo(fileName);
- process.Start();
- }
-
- public float Scale = 1.0F;
- public string UnitsDescription = "Scale in usec";
-
- // TODO: probabably does not belong in this class.
- public void CaptureCurrentMachineInfo(Assembly assemblyWithCode, bool skipMachineStats) {
- this["Computer Name"] = Environment.MachineName;
- if (!skipMachineStats) {
- ////ComputerSpecs specs = new ComputerSpecs();
- ////this["Number of Processors"] = specs.NumberOfProcessors;
- ////this["Processor Name "] = specs.ProcessorName;
- ////this["Processor Mhz"] = specs.ProcessorClockSpeedMhz;
- ////this["Memory MBytes"] = specs.MemoryMBytes;
- ////this["L1 Cache KBytes"] = specs.L1KBytes;
- ////this["L2 Cache KBytes"] = specs.L2KBytes;
- ////this["Operating System"] = specs.OperatingSystem;
- ////this["Operating System Version"] = specs.OperatingSystemVersion;
- ////this["Stopwatch resolution (nsec)"] = (CodeTimer.ResolutionUsec * 1000.0).ToString("f3");
- }
-
- this["Machine Word Size (Bits)"] = (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) * 8).ToString();
-
- this["CLR Version"] = Environment.Version.ToString();
- this["CLR Directory"] = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
-
- // Are we NGENed or JITTed?
- if (IsNGenedCodeLoaded(assemblyWithCode))
- this["CompileType"] = "NGEN";
- else
- this["CompileType"] = "JIT";
-
- // Are we Appdomain Shared, or not?
- MethodInfo currentMethod = Assembly.GetEntryAssembly().EntryPoint;
- LoaderOptimizationAttribute loaderAttribute = (LoaderOptimizationAttribute)System.Attribute.GetCustomAttribute(currentMethod, typeof(LoaderOptimizationAttribute));
- if (loaderAttribute != null && loaderAttribute.Value == LoaderOptimization.MultiDomain)
- this["CodeSharing"] = "AppDomainShared";
- else
- this["CodeSharing"] = "AppDomainSpecific";
-
- this["CodeOptimization"] = IsOptimized(assemblyWithCode) ? "Optimized" : "Unoptimized";
- }
-
- internal static bool IsOptimized(Assembly assembly) {
- DebuggableAttribute debugAttribute = (DebuggableAttribute)System.Attribute.GetCustomAttribute(assembly, typeof(System.Diagnostics.DebuggableAttribute));
- if (debugAttribute != null && debugAttribute.IsJITOptimizerDisabled)
- return false;
- else
- return true;
- }
-
- static bool IsNGenedCodeLoaded(Assembly assembly) {
- // This is a bit of a hack, basically I find the assemblies file name, then
- // look for a module loaded called '<filename>.ni.<ext>'. It is not foolproof,
- // but it more than good enough for most purposes.
- string assemblyFileName = Path.GetFileName(assembly.ManifestModule.FullyQualifiedName);
- string nativeImageExt = "ni" + Path.GetExtension(assemblyFileName);
- string nativeImageSuffix = @"\" + Path.ChangeExtension(assemblyFileName, nativeImageExt);
-
- System.Diagnostics.Process myProcess = System.Diagnostics.Process.GetCurrentProcess();
- foreach (System.Diagnostics.ProcessModule module in myProcess.Modules) {
- if (module.FileName.EndsWith(nativeImageSuffix, StringComparison.OrdinalIgnoreCase))
- return true;
- }
- return false;
- }
-
- #region privates
- Dictionary<string, object> attributes;
- StatsCollection dataSet;
- string category;
-
- #endregion
- }
-
- /// <summary>
- /// StatsCollection represents a collecton of named of samples (class
- /// Stats) that have have been given string names. The data can be
- /// looked up by name, but is also collection also remembers the order in
- /// which the samples were added, and the names can be enumerated in that
- /// order.
- /// </summary>
- internal class StatsCollection {
- public StatsCollection() {
- dict = new Dictionary<string, Stats>();
- order = new List<string>();
- }
-
- public Stats this[string key] { get { return dict[key]; } }
- public bool ContainsKey(string key) { return dict.ContainsKey(key); }
- public IEnumerable<string> Keys { get { return order; } }
- public void Add(string key, Stats value) {
- dict.Add(key, value);
- order.Add(key);
- }
- public void WriteReportTable(TextWriter writer, float scale) {
- writer.WriteLine("<table border>");
- writer.WriteLine("<tr><th>Name</th><th>Median</th><th>Mean</th><th>StdDev</th><th>Min</th><th>Max</th><th>Samples</th></tr>");
-
- foreach (string key in this.Keys) {
- Stats value = this[key];
- writer.Write("<tr>");
- writer.Write("<td>" + HttpUtility.HtmlEncode(key) + "</td>");
- writer.Write("<td>" + (value.Median / scale).ToString("f3") + "</td>");
- writer.Write("<td>" + (value.Mean / scale).ToString("f3") + "</td>");
- writer.Write("<td>" + (value.StandardDeviation / scale).ToString("f3") + "</td>");
- writer.Write("<td>" + (value.Minimum / scale).ToString("f3") + "</td>");
- writer.Write("<td>" + (value.Maximum / scale).ToString("f3") + "</td>");
- writer.Write("<td>" + value.Count + "</td>");
- writer.WriteLine("</tr>");
- }
- writer.WriteLine("</table>");
- }
-
- #region privates
- Dictionary<string, Stats> dict;
- List<string> order;
- #endregion
- }
-}
-
diff --git a/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs b/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs
index 1077514..33a177a 100644
--- a/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs
+++ b/src/DotNetOpenAuth.Test/Performance/PerformanceTestUtilities.cs
@@ -1,20 +1,20 @@
-namespace DotNetOpenAuth.Test.Performance {
+//-----------------------------------------------------------------------
+// <copyright file="PerformanceTestUtilities.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Performance {
using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using log4net;
- using NUnit.Framework;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.RelyingParty;
- using System.Threading;
using System.Diagnostics;
+ using System.Reflection;
+ using System.Threading;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using NUnit.Framework;
internal static class PerformanceTestUtilities {
internal static Stats Baseline;
- private static readonly StatsCollection data = new StatsCollection();
-
static PerformanceTestUtilities() {
Baseline = CollectBaseline();
TestUtilities.TestLogger.InfoFormat(
@@ -22,8 +22,13 @@
Baseline.Median * 1000);
}
+ internal static bool IsOptimized(Assembly assembly) {
+ DebuggableAttribute debugAttribute = (DebuggableAttribute)System.Attribute.GetCustomAttribute(assembly, typeof(System.Diagnostics.DebuggableAttribute));
+ return debugAttribute == null || !debugAttribute.IsJITOptimizerDisabled;
+ }
+
internal static Stats Measure(Action action, float maximumAllowedUnitTime, int samples = 10, int iterations = 100, string name = null) {
- if (!StatsLogger.IsOptimized(typeof(OpenIdRelyingParty).Assembly)) {
+ if (!IsOptimized(typeof(OpenIdRelyingParty).Assembly)) {
Assert.Inconclusive("Unoptimized code.");
}
@@ -67,11 +72,11 @@
for (hits = 0; hits < hitsRequired; hits++) {
float currentCpuUtilization = pc.NextValue();
if (currentCpuUtilization > maximumCpuUtilization) {
- //Console.WriteLine("Miss: CPU at {0}% utilization", currentCpuUtilization);
+ ////Console.WriteLine("Miss: CPU at {0}% utilization", currentCpuUtilization);
break;
}
- //Console.WriteLine("Hit: CPU at {0}% utilization", currentCpuUtilization);
+ ////Console.WriteLine("Hit: CPU at {0}% utilization", currentCpuUtilization);
Thread.Sleep(samplingInterval);
}
@@ -88,18 +93,21 @@
private static Stats CollectBaseline() {
using (new HighPerformance()) {
- return new MultiSampleCodeTimer(10, 1000).Measure("MethodCalls: EmptyStaticFunction()", 10, delegate {
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- });
+ return new MultiSampleCodeTimer(10, 1000).Measure(
+ "MethodCalls: EmptyStaticFunction()",
+ 10,
+ delegate {
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ });
}
}
@@ -109,55 +117,4 @@
}
}
}
-
- /// <summary>
- /// Suppresses logging and forces the CPU into a high performance mode.
- /// </summary>
- internal class HighPerformance : IDisposable {
- private readonly log4net.Core.Level originalLoggerThreshold;
- private readonly PowerManagment.PowerSetting powerSetting;
- private readonly ProcessPriorityClass originalProcessPriority;
-
-#pragma warning disable 0618
- /// <summary>
- /// Initializes a new instance of the <see cref="HighPerformance"/> class.
- /// </summary>
- internal HighPerformance() {
- if (!PerformanceTestUtilities.CoolOff()) {
- Assert.Inconclusive("Timed out waiting for a quiet CPU in which to perform perf tests.");
- }
-
- this.originalLoggerThreshold = LogManager.GetLoggerRepository().Threshold;
- LogManager.GetLoggerRepository().Threshold = LogManager.GetLoggerRepository().LevelMap["OFF"];
- this.powerSetting = new PowerManagment.PowerSetting(PowerManagment.PowerProfiles.HighPerformance);
- this.originalProcessPriority = Process.GetCurrentProcess().PriorityClass;
- Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
- Thread.CurrentThread.Priority = ThreadPriority.Highest;
- HighCpu();
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose() {
- Thread.CurrentThread.Priority = ThreadPriority.Normal;
- Process.GetCurrentProcess().PriorityClass = this.originalProcessPriority;
- this.powerSetting.Dispose(); // restores original power setting.
- LogManager.GetLoggerRepository().Threshold = this.originalLoggerThreshold;
- }
-#pragma warning restore 0618
-
- /// <summary>
- /// Runs the CPU in a tight loop to get it out of any low power state.
- /// </summary>
- private static void HighCpu() {
- int dummy;
- new MultiSampleCodeTimer(10, 1000).Measure("Loop 1K times", 1, delegate {
- int k = 0;
- while (k < 1000)
- k++; // still in danger of being optimized.
- dummy = k; // avoid optimization.
- });
- }
- }
}
diff --git a/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs b/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs
index 66492f3..81c6e7a 100644
--- a/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs
+++ b/src/DotNetOpenAuth.Test/Performance/PowerManagement.cs
@@ -6,23 +6,15 @@
namespace DotNetOpenAuth.Test.Performance {
using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
using System.ComponentModel;
+ using System.Diagnostics;
+ using System.Runtime.InteropServices;
/// <summary>
/// PowerManagement allows you to access the funtionality of the Control Panel -> Power Options
/// dialog in windows. (Currently we only use VISTA APIs).
/// </summary>
internal static class PowerManagment {
- internal static class PowerProfiles {
- internal static Guid HighPerformance = new Guid(0x8c5e7fda, 0xe8bf, 0x4a96, 0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c);
-
- internal static Guid Balanced = new Guid(0x381b4222, 0xf694, 0x41f0, 0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e);
-
- internal static Guid PowerSaver = new Guid(0xa1841308, 0x3541, 0x4fab, 0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a);
- }
-
internal static unsafe Guid CurrentPolicy {
get {
Guid* retPolicy = null;
@@ -33,7 +25,8 @@ namespace DotNetOpenAuth.Test.Performance {
ret = *retPolicy;
Marshal.FreeHGlobal((IntPtr)retPolicy);
}
- } catch (Exception) { }
+ } catch (Exception) {
+ }
return ret;
}
@@ -46,6 +39,20 @@ namespace DotNetOpenAuth.Test.Performance {
}
}
+ [DllImport("powrprof.dll")]
+ private static unsafe extern int PowerGetActiveScheme(IntPtr reservedZero, ref Guid* policyGuidRet);
+
+ [DllImport("powrprof.dll")]
+ private static extern int PowerSetActiveScheme(IntPtr reservedZero, ref Guid policyGuid);
+
+ internal static class PowerProfiles {
+ internal static Guid HighPerformance = new Guid(0x8c5e7fda, 0xe8bf, 0x4a96, 0x9a, 0x85, 0xa6, 0xe2, 0x3a, 0x8c, 0x63, 0x5c);
+
+ internal static Guid Balanced = new Guid(0x381b4222, 0xf694, 0x41f0, 0x96, 0x85, 0xff, 0x5b, 0xb2, 0x60, 0xdf, 0x2e);
+
+ internal static Guid PowerSaver = new Guid(0xa1841308, 0x3541, 0x4fab, 0xbc, 0x81, 0xf7, 0x15, 0x56, 0xf2, 0x0b, 0x4a);
+ }
+
internal class PowerSetting : IDisposable {
/// <summary>
/// The power policy in effect when this instance was constructed.
@@ -72,11 +79,5 @@ namespace DotNetOpenAuth.Test.Performance {
}
}
}
-
- [DllImport("powrprof.dll")]
- private static unsafe extern int PowerGetActiveScheme(IntPtr ReservedZero, ref Guid* policyGuidRet);
-
- [DllImport("powrprof.dll")]
- private static extern int PowerSetActiveScheme(IntPtr ReservedZero, ref Guid policyGuid);
}
} \ No newline at end of file