我想对面向 .NET 6.0 和 .NET Framework 4.8 的 WPF 类库中的类进行基准测试。这是项目文件:
WpfClassLibrary.cs:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-windows;net4.8</TargetFrameworks>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>
我要测试的类,简单实例化一个
System.Windows.Documents.FlowDocument
对象:
namespace WpfClassLibrary
{
using System.Windows.Documents;
public class WpfClass
{
public FlowDocument Document { get; } = new FlowDocument();
}
}
这是基准测试项目的项目文件:
基准测试WpfClassLibrary.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0-windows;net4.8</TargetFrameworks>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WpfClassLibrary\WpfClassLibrary.csproj" />
</ItemGroup>
</Project>
以及基准本身:
程序.cs:
namespace Benchmarks
{
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using WpfClassLibrary;
internal class Program
{
static void Main(string[] args)
{
var results = BenchmarkRunner.Run<WpfClassBenchmarks>();
}
}
//[SimpleJob(RuntimeMoniker.Net48)]
//[SimpleJob(RuntimeMoniker.Net60)]
public class WpfClassBenchmarks
{
[Benchmark]
public void WpfClass()
{
_ = new WpfClass();
}
}
}
如果我按原样运行,则基准测试会构建并运行良好。但是,如果我注释掉两个
SimpleJob
属性,.NET Framework 4.8 基准测试可以正常构建并运行,但 .NET 6.0 基准测试则不然。我收到以下错误:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.IO.FileNotFoundException: Could not load file or assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
at WpfClassLibrary.WpfClass..ctor()
at Benchmarks.WpfClassBenchmarks.WpfClass() in C:\Users\stevensd\source\BenchmarkingWpfClassLibrary\Benchmarks\Program.cs:line 23
at BenchmarkDotNet.Autogenerated.Runnable_0.WorkloadActionNoUnroll(Int64 invokeCount) in C:\Users\stevensd\source\BenchmarkingWpfClassLibrary\Benchmarks\bin\Release\net6.0-windows\7eaf257f-9929-493b-9995-b7827893b4db\7eaf257f-9929-493b-9995-b7827893b4db.notcs:line 311
at BenchmarkDotNet.Engines.Engine.RunIteration(IterationData data)
at BenchmarkDotNet.Engines.EngineFactory.Jit(Engine engine, Int32 jitIndex, Int32 invokeCount, Int32 unrollFactor)
at BenchmarkDotNet.Engines.EngineFactory.CreateReadyToRun(EngineParameters engineParameters)
at BenchmarkDotNet.Autogenerated.Runnable_0.Run(IHost host, String benchmarkName) in C:\Users\stevensd\source\BenchmarkingWpfClassLibrary\Benchmarks\bin\Release\net6.0-windows\7eaf257f-9929-493b-9995-b7827893b4db\7eaf257f-9929-493b-9995-b7827893b4db.notcs:line 176
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args) in C:\Users\stevensd\source\BenchmarkingWpfClassLibrary\Benchmarks\bin\Release\net6.0-windows\7eaf257f-9929-493b-9995-b7827893b4db\7eaf257f-9929-493b-9995-b7827893b4db.notcs:line 57
我认为发生的情况是,当未指定
SimpleJob
属性时,BenchmarkDotNet 正在使用适当的 net6.0-windows
名称构建基准。但是,当将 SimpleJob
属性与绰号 RuntimeMoniker.Net60
一起使用时,它是使用不正确的 net6.0
构建的。
如何指定一个使用运行时名称
net60-windows
而不是 net60
的简单作业?
源代码:https://github.com/DanStevens/BenchmarkingWpfClassLibrary
我认为您需要使用
IConfig
以编程方式执行此操作,即您不能直接使用 SimpleJobAttribute
:
internal class Program
{
static void Main(string[] args)
{
var results = BenchmarkRunner.Run<WpfClassBenchmarks>(
ManualConfig.Create(DefaultConfig.Instance)
.AddJob(Job.Default.WithRuntime(ClrRuntime.Net48))
.AddJob(Job.Default.WithToolchain(
CsProjCoreToolchain.From(
new NetCoreAppSettings(
targetFrameworkMoniker: "net6.0-windows",
runtimeFrameworkVersion: null,
name: "6.0")))));
}
}
public class WpfClassBenchmarks
{
[Benchmark]
public void WpfClass()
{
_ = new WpfClass();
}
}