Skip to content

Commit

Permalink
created MeasurementConfigurator<T>
Browse files Browse the repository at this point in the history
finished implementing configurator searching within ReflectionDiscovery
refactored the internals of BenchmarkSettings and ReflectionDiscovery to use configurators
close petabridge#67 - fixed warmup with no numbers issue
close petabridge#61 Added NBench.PerformanceCounters
  • Loading branch information
Aaronontheweb committed Mar 20, 2016
1 parent 0771ca7 commit 84eea83
Show file tree
Hide file tree
Showing 69 changed files with 1,797 additions and 478 deletions.
15 changes: 14 additions & 1 deletion NBench.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{C8104500-2C0F-46A2-AE84-A3D74CC55697}"
EndProject
Expand Down Expand Up @@ -33,6 +33,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBench.Tests.Performance",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBench.Tests.Assembly", "tests\NBench.Tests.Assembly\NBench.Tests.Assembly.csproj", "{96FCB3AB-8C76-4BD0-B97F-1239E5FF5C5C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBench.PerformanceCounters", "src\NBench.PerformanceCounters\NBench.PerformanceCounters.csproj", "{3112B845-6A64-4AD2-9FA9-88F47BE980C8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBench.PeformanceCounters.Tests.End2End", "tests\NBench.PeformanceCounters.Tests.End2End\NBench.PeformanceCounters.Tests.End2End.csproj", "{416A4BAD-459C-4896-A44C-4C2344EBE154}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -67,6 +71,14 @@ Global
{96FCB3AB-8C76-4BD0-B97F-1239E5FF5C5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96FCB3AB-8C76-4BD0-B97F-1239E5FF5C5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96FCB3AB-8C76-4BD0-B97F-1239E5FF5C5C}.Release|Any CPU.Build.0 = Release|Any CPU
{3112B845-6A64-4AD2-9FA9-88F47BE980C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3112B845-6A64-4AD2-9FA9-88F47BE980C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3112B845-6A64-4AD2-9FA9-88F47BE980C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3112B845-6A64-4AD2-9FA9-88F47BE980C8}.Release|Any CPU.Build.0 = Release|Any CPU
{416A4BAD-459C-4896-A44C-4C2344EBE154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{416A4BAD-459C-4896-A44C-4C2344EBE154}.Debug|Any CPU.Build.0 = Debug|Any CPU
{416A4BAD-459C-4896-A44C-4C2344EBE154}.Release|Any CPU.ActiveCfg = Release|Any CPU
{416A4BAD-459C-4896-A44C-4C2344EBE154}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -77,5 +89,6 @@ Global
{B7F38539-67A1-42B8-A5E5-CB592B6E3233} = {1F1914B9-8F67-4B51-9738-CDE5AFB2F8DE}
{E3730D65-70AE-4055-A291-800044C48FDD} = {1F1914B9-8F67-4B51-9738-CDE5AFB2F8DE}
{96FCB3AB-8C76-4BD0-B97F-1239E5FF5C5C} = {1F1914B9-8F67-4B51-9738-CDE5AFB2F8DE}
{416A4BAD-459C-4896-A44C-4C2344EBE154} = {1F1914B9-8F67-4B51-9738-CDE5AFB2F8DE}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Copyright (c) Petabridge <https://petabridge.com/>. All rights reserved.
// Licensed under the Apache 2.0 license. See LICENSE file in the project root for full license information.

using System;
using System.Diagnostics;
using NBench.Collection;
using NBench.Metrics;

namespace NBench.Collection
namespace NBench.PerformanceCounters.Collection
{
/// <summary>
/// A <see cref="MetricCollector" /> implementation that uses a <see cref="PerformanceCounter" />
/// internally to record various system metrics.
/// </summary>
public class PerformanceCounterMetricCollector : MetricCollector, IDisposable
public class PerformanceCounterMetricCollector : MetricCollector
{
private PerformanceCounter _counter;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using NBench.Collection;
using NBench.Metrics;
using NBench.PerformanceCounters.Metrics;
using NBench.Sdk;
using NBench.Sys;

namespace NBench.PerformanceCounters.Collection
{
/// <summary>
/// Factory that actually creates <see cref="PerformanceCounter"/> instances internally
/// to correspond with each <see cref="PerformanceCounterBenchmarkSetting"/>
/// </summary>
public class PerformanceCounterSelector : MetricsCollectorSelector
{
public PerformanceCounterSelector() : this(PerformanceCounterMetricName.DefaultName) { }

public PerformanceCounterSelector(MetricName name) : base(name)
{
}

public PerformanceCounterSelector(MetricName name, SysInfo systemInfo) : base(name, systemInfo)
{
}

public override MetricCollector Create(RunMode runMode, WarmupData warmup, IBenchmarkSetting setting)
{
Contract.Assert(setting != null);
Contract.Assert(setting is PerformanceCounterBenchmarkSetting);
var counterBenchmarkSetting = setting as PerformanceCounterBenchmarkSetting;
var name = counterBenchmarkSetting.PerformanceCounterMetric;

try
{
var performanceCounter = new PerformanceCounter(name.CategoryName, name.CounterName,
name.InstanceName ?? string.Empty, true);

return new PerformanceCounterMetricCollector(name, name.UnitName ?? MetricNames.DefaultUnitName, performanceCounter, true);
}
catch (Exception ex)
{
throw new NBenchException($"Failed to create PerformanceCounterMeasurement {name.ToHumanFriendlyString()} - internal error while creating performance counter.", ex);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using NBench.Metrics;
using NBench.Sdk;

namespace NBench.PerformanceCounters.Metrics
{
/// <summary>
/// <see cref="IBenchmarkSetting"/> used to instrument performance counters inside a <see cref="Benchmark"/>
/// </summary>
public sealed class PerformanceCounterBenchmarkSetting : IBenchmarkSetting, IEquatable<PerformanceCounterBenchmarkSetting>
{
public PerformanceCounterBenchmarkSetting(PerformanceCounterMetricName performanceCounterMetric, AssertionType assertionType, Assertion assertion)
{
PerformanceCounterMetric = performanceCounterMetric;
AssertionType = assertionType;
Assertion = assertion;
}

public PerformanceCounterMetricName PerformanceCounterMetric { get; }

public MetricName MetricName => PerformanceCounterMetric;
public AssertionType AssertionType { get; }
public Assertion Assertion { get; }

public bool Equals(IBenchmarkSetting other)
{
return (other is PerformanceCounterBenchmarkSetting)
&& Equals((PerformanceCounterBenchmarkSetting) other);
}


public bool Equals(PerformanceCounterBenchmarkSetting other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return PerformanceCounterMetric.Equals(other.PerformanceCounterMetric)
&& AssertionType == other.AssertionType
&& Assertion.Equals(other.Assertion);
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((PerformanceCounterBenchmarkSetting) obj);
}

public override int GetHashCode()
{
unchecked
{
var hashCode = PerformanceCounterMetric.GetHashCode();
hashCode = (hashCode*397) ^ (int) AssertionType;
hashCode = (hashCode*397) ^ Assertion.GetHashCode();
return hashCode;
}
}

public static bool operator ==(PerformanceCounterBenchmarkSetting left, PerformanceCounterBenchmarkSetting right)
{
return Equals(left, right);
}

public static bool operator !=(PerformanceCounterBenchmarkSetting left, PerformanceCounterBenchmarkSetting right)
{
return !Equals(left, right);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Diagnostics.Contracts;
using NBench.Metrics;

namespace NBench.PerformanceCounters.Metrics
{
/// <summary>
/// Uniquely represents a performance counter measurement name inside our collections engine
/// </summary>
public sealed class PerformanceCounterMetricName : MetricName, IEquatable<PerformanceCounterMetricName>
{
public static readonly PerformanceCounterMetricName DefaultName = new PerformanceCounterMetricName("Category", "Instance", "Instance", "Units");

public PerformanceCounterMetricName(string categoryName, string counterName, string instanceName, string unitName)
{
Contract.Requires(categoryName != null);
Contract.Requires(counterName != null);
CategoryName = categoryName;
CounterName = counterName;
InstanceName = instanceName;
UnitName = unitName;
}

/// <summary>
/// The name of the performance counter category with which this performance counter is associated.
/// </summary>
public string CategoryName { get; }

/// <summary>
/// The name of the performance counter.
/// </summary>
public string CounterName { get; }

/// <summary>
/// The name of the performance counter category instance, or an empty string (""), if the category contains a single instance.
/// </summary>
public string InstanceName { get; }

/// <summary>
/// Human-readable name of the measurement units associated with this performance counter.
///
/// Used solely for reporting purposes - designed to make it easier to understand what the metric reads.
/// For instance, if this performance counter was measuring disk writes the unit name would be "bytes"
/// Or if this performance counter were measuring page faults, the unit name would be "page faults"
/// </summary>
public string UnitName { get; }

public override bool Equals(MetricName other)
{
return other is PerformanceCounterMetricName
&& Equals((PerformanceCounterMetricName) other);
}

public bool Equals(PerformanceCounterMetricName other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(CategoryName, other.CategoryName)
&& string.Equals(CounterName, other.CounterName)
&& string.Equals(InstanceName, other.InstanceName);
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((PerformanceCounterMetricName) obj);
}

public override int GetHashCode()
{
unchecked
{
var hashCode = CategoryName?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ (CounterName?.GetHashCode() ?? 0);
hashCode = (hashCode*397) ^ (InstanceName?.GetHashCode() ?? 0);
return hashCode;
}
}

public static bool operator ==(PerformanceCounterMetricName left, PerformanceCounterMetricName right)
{
return Equals(left, right);
}

public static bool operator !=(PerformanceCounterMetricName left, PerformanceCounterMetricName right)
{
return !Equals(left, right);
}

public override string ToHumanFriendlyString()
{
if(!string.IsNullOrEmpty(InstanceName))
return $"[PerformanceCounter] {CategoryName}:{CounterName}:{InstanceName}";
return $"[PerformanceCounter] {CategoryName}:{CounterName}";
}
}
}
65 changes: 65 additions & 0 deletions src/NBench.PerformanceCounters/NBench.PerformanceCounters.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3112B845-6A64-4AD2-9FA9-88F47BE980C8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NBench.PerformanceCounters</RootNamespace>
<AssemblyName>NBench.PerformanceCounters</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Collection\PerformanceCounterSelector.cs" />
<Compile Include="Metrics\PerformanceCounterBenchmarkSetting.cs" />
<Compile Include="Metrics\PerformanceCounterMetricName.cs" />
<Compile Include="PerformanceCounterMeasurementAttribute.cs" />
<Compile Include="Collection\PerformanceCounterMetricCollector.cs" />
<Compile Include="PerformanceCounterMeasurementConfigurator.cs" />
<Compile Include="PerformanceCounterThroughputAssertionAttribute.cs" />
<Compile Include="PerformanceCounterTotalAssertionAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NBench\NBench.csproj">
<Project>{4e0b1852-7b6d-49e7-9939-a315d086b094}</Project>
<Name>NBench</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Loading

0 comments on commit 84eea83

Please sign in to comment.