dotnet / BenchmarkDotNet

Powerful .NET library for benchmarking
https://benchmarkdotnet.org
MIT License
10.48k stars 963 forks source link

Support netcoreapp2.1 #587

Closed eerhardt closed 6 years ago

eerhardt commented 6 years ago

When I try running a BenchmarkDotNet project that looks like the following:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="BenchmarkDotNet" Version="0.10.10" />
  </ItemGroup>
</Project>

I get the errors:

// Exception:   Restoring packages for /home/eerhardt/DotNetTest/RefOverloadsPerfTests/bin/Release/netcoreapp2.1/7d0199c9-e7ac-414c-b788-16da68c57138/BenchmarkDotNet.Autogenerated.csproj...
/home/eerhardt/DotNetTest/RefOverloadsPerfTests/bin/Release/netcoreapp2.1/7d0199c9-e7ac-414c-b788-16da68c57138/BenchmarkDotNet.Autogenerated.csproj : error NU1201: Project RefOverloadsPerfTests is not compatible with netcoreapp2.0 (.NETCoreApp,Version=v2.0). Project RefOverloadsPerfTests supports: netcoreapp2.1 (.NETCoreApp,Version=v2.1)
  Generating MSBuild file /home/eerhardt/DotNetTest/RefOverloadsPerfTests/bin/Release/netcoreapp2.1/7d0199c9-e7ac-414c-b788-16da68c57138/obj/BenchmarkDotNet.Autogenerated.csproj.nuget.g.props.
  Generating MSBuild file /home/eerhardt/DotNetTest/RefOverloadsPerfTests/bin/Release/netcoreapp2.1/7d0199c9-e7ac-414c-b788-16da68c57138/obj/BenchmarkDotNet.Autogenerated.csproj.nuget.g.targets.
  Restore failed in 131.93 ms for /home/eerhardt/DotNetTest/RefOverloadsPerfTests/bin/Release/netcoreapp2.1/7d0199c9-e7ac-414c-b788-16da68c57138/BenchmarkDotNet.Autogenerated.csproj.

I'm using the latest .NET Core SDK from the master branch: https://github.com/dotnet/cli#installers-and-binaries and I have a NuGet.config that points to the daily builds of .NET Core:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
      <add key="nuget" value="https://api.nuget.org/v3/index.json" />
      <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
  </packageSources>
</configuration>

I expected this to just work, like it does for netcoreapp2.0.

adamsitnik commented 6 years ago

@eerhardt big thanks for providing the bug report and the fix!

eerhardt commented 6 years ago

No problem. Big thanks for the tool that is making my life easier! 😉

qbit86 commented 5 years ago

I have the same issue on fresh 0.11.2:

error NU1201: Проект Misnomer.Rist.Benchmark несовместим с netcoreapp2.0 (.NETCoreApp,Version=v2.0)

Why does it even try to use 2.0? I don't have not a single mentioning of netcoreapp2.0 in the whole project, only netcoreapp2.1 everywhere.

I have just updated to the latest .NET Core 2.1, both Runtime and SDK. Even tried dotnet nuget locals all --clear, nothing helps.

adamsitnik commented 5 years ago

@qbit86 what are the target frameworks defined in you project with benchmarks?

qbit86 commented 5 years ago

@adamsitnik

what are the target frameworks defined in you project with benchmarks?

<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
qbit86 commented 5 years ago

@adamsitnik

This benchmark works fine on my home machine, but not on my work machine. The config is:

// https://benchmarkdotnet.org/articles/configs/configs.html
Job clrLegacyJitJob = new Job(Job.Default)
    .With(Runtime.Clr)
    .With(Platform.X86)
    .With(Jit.LegacyJit)
    .ApplyAndFreeze(RunMode.Short);

Job clrRyuJitJob = new Job(Job.Default)
    .With(Runtime.Clr)
    .With(Platform.X64)
    .With(Jit.RyuJit)
    .ApplyAndFreeze(RunMode.Short);

Job coreRyuJitJob = new Job(Job.Default)
    .With(Runtime.Core)
    .With(Platform.X64)
    .With(Jit.RyuJit)
    .ApplyAndFreeze(RunMode.Short);

IConfig config = ManualConfig.Create(DefaultConfig.Instance)
    .With(MemoryDiagnoser.Default)
    .With(clrLegacyJitJob)
    .With(clrRyuJitJob)
    .With(coreRyuJitJob);

Summary _ = BenchmarkRunner.Run<StringJoinBenchmark>(config);
adamsitnik commented 5 years ago

So BDN has two processes: host (what you run in the console) and child processes (for defined jobs)

When you run the host process as .NET Core app (dotnet run -f netcoreapp2.1) we can check the .NET Core version (by using some reflection on loaded types) and we use the same version for running the benchmarks.

However, when the host process is .NET (dotnet run -f net471) we can't check .NET Core version and we use 2.0 as the default.

So in your case, I suspect that you run the host process as net471 and we use the default value.

Suggested fix: make it explicit in the config that you want .NET Core 2.1 or always run the benchmarks from .NET Core host app (it can use relfection to check .NET Version and read registry keys to find out .NET SDK version)

.With(CsProjCoreToolchain.NetCoreApp21);
qbit86 commented 5 years ago

@adamsitnik Thanks for clarification!

.With(CsProjCoreToolchain.NetCoreApp21);

I've tried this, but it produces one more column in result table (Toolchain), which I'd prefer to avoid.

Ok, another difference is that I've run benchmark with Rider on my home machine and with Visual Studio on my work machine. Can it make the difference?

So in your case, I suspect that you run the host process as net471 and we use the default value.

Then how can I make Visual Studio to use netcoreapp2.1 on Ctrl+F5?

adamsitnik commented 5 years ago

image