Skip to content

Commit

Permalink
Use an auto-incremented id instead of guid.
Browse files Browse the repository at this point in the history
Always use same ProgramName regardless of --keepFiles.
Include benchmark assembly name in ProgramName.
  • Loading branch information
timcassell committed Dec 12, 2024
1 parent 072337e commit 6906de3
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 18 deletions.
16 changes: 10 additions & 6 deletions src/BenchmarkDotNet/Running/BuildPartition.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using BenchmarkDotNet.Characteristics;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
Expand All @@ -18,15 +19,20 @@ namespace BenchmarkDotNet.Running
{
public class BuildPartition
{
// We use an auto-increment global counter instead of Guid to guarantee uniqueness per benchmark run (Guid has a small chance to collide),
// assuming there are fewer than 4 billion build partitions (a safe assumption).
private static int s_partitionCounter;

public BuildPartition(BenchmarkBuildInfo[] benchmarks, IResolver resolver)
{
Resolver = resolver;
RepresentativeBenchmarkCase = benchmarks[0].BenchmarkCase;
Benchmarks = benchmarks;
var keepBenchmarkFiles = benchmarks[0].Config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles);
var guid = Guid.NewGuid().ToString();
ProgramName = keepBenchmarkFiles ? RepresentativeBenchmarkCase.Job.FolderInfo : guid;
ProgramDirectory = keepBenchmarkFiles ? Path.Combine(RepresentativeBenchmarkCase.Job.FolderInfo, guid) : guid;
// Combine the benchmark's assembly name, folder info, and build partition id.
string benchmarkAssemblyName = RepresentativeBenchmarkCase.Descriptor.Type.Assembly.GetName().Name;
string folderInfo = RepresentativeBenchmarkCase.Job.FolderInfo;
int id = Interlocked.Increment(ref s_partitionCounter);
ProgramName = $"{benchmarkAssemblyName}-{folderInfo}-{id}";
LogBuildOutput = benchmarks[0].Config.Options.IsSet(ConfigOptions.LogBuildOutput);
GenerateMSBuildBinLog = benchmarks[0].Config.Options.IsSet(ConfigOptions.GenerateMSBuildBinLog);
}
Expand All @@ -35,8 +41,6 @@ public BuildPartition(BenchmarkBuildInfo[] benchmarks, IResolver resolver)

public string ProgramName { get; }

public string ProgramDirectory { get; }

/// <summary>
/// the benchmarks are grouped by the build settings
/// so you can use this benchmark to get the runtime settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ protected DotNetCliGenerator(string targetFrameworkMoniker, string cliPath, stri
/// we are limited by xprojs (by default compiles all .cs files in all subfolders, Program.cs could be doubled and fail the build)
/// and also by NuGet internal implementation like looking for global.json file in parent folders
/// </summary>
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programDirectory)
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)
{
if (GetSolutionRootDirectory(out var directoryInfo))
{
return Path.Combine(directoryInfo.FullName, programDirectory);
return Path.Combine(directoryInfo.FullName, programName);
}

// we did not find global.json or any Visual Studio solution file?
// let's return it in the old way and hope that it works ;)
var parent = new DirectoryInfo(Directory.GetCurrentDirectory()).Parent;
if (parent == null)
throw new DirectoryNotFoundException("Parent directory for current directory");
return Path.Combine(parent.FullName, programDirectory);
return Path.Combine(parent.FullName, programName);
}

internal static bool GetSolutionRootDirectory(out DirectoryInfo directoryInfo)
Expand Down
6 changes: 3 additions & 3 deletions src/BenchmarkDotNet/Toolchains/GeneratorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger log
/// <summary>
/// returns a path to the folder where auto-generated project and code are going to be placed
/// </summary>
[PublicAPI] protected abstract string GetBuildArtifactsDirectoryPath(BuildPartition assemblyLocation, string programDirectory);
[PublicAPI] protected abstract string GetBuildArtifactsDirectoryPath(BuildPartition assemblyLocation, string programName);

/// <summary>
/// returns a path where executable should be found after the build (usually \bin)
Expand Down Expand Up @@ -128,10 +128,10 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r
// its not ".cs" in order to avoid VS from displaying and compiling it with xprojs/csprojs that include all *.cs by default
const string codeFileExtension = ".notcs";

string buildArtifactsDirectoryPath = GetBuildArtifactsDirectoryPath(buildPartition, buildPartition.ProgramDirectory);
string programName = buildPartition.ProgramName;
string buildArtifactsDirectoryPath = GetBuildArtifactsDirectoryPath(buildPartition, programName);
string binariesDirectoryPath = GetBinariesDirectoryPath(buildArtifactsDirectoryPath, buildPartition.BuildConfiguration);

string programName = buildPartition.ProgramName;
string executablePath = GetExecutablePath(binariesDirectoryPath, programName);

return new ArtifactsPaths(
Expand Down
6 changes: 3 additions & 3 deletions src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ internal Generator(string ilCompilerVersion,

protected override string GetExecutableExtension() => OsDetector.ExecutableExtension;

protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programDirectory)
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)
=> useTempFolderForRestore
? Path.Combine(Path.GetTempPath(), programDirectory) // store everything in temp to avoid collisions with IDE
: base.GetBuildArtifactsDirectoryPath(buildPartition, programDirectory);
? Path.Combine(Path.GetTempPath(), programName) // store everything in temp to avoid collisions with IDE
: base.GetBuildArtifactsDirectoryPath(buildPartition, programName);

protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, runtimeIdentifier, "publish");
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace BenchmarkDotNet.Toolchains.Roslyn
[PublicAPI]
public class Generator : GeneratorBase
{
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programDirectory)
protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName)
=> Path.GetDirectoryName(buildPartition.AssemblyLocation);

[PublicAPI]
Expand Down
4 changes: 2 additions & 2 deletions tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ public void TestAssemblyFilePathIsUsedWhenTheAssemblyLocationIsNotEmpty()

private class SteamLoadedBuildPartition : CsProjGenerator
{
internal string ResolvePathForBinaries(BuildPartition buildPartition, string programDirectory)
internal string ResolvePathForBinaries(BuildPartition buildPartition, string programName)
{
return base.GetBuildArtifactsDirectoryPath(buildPartition, programDirectory);
return base.GetBuildArtifactsDirectoryPath(buildPartition, programName);
}

public SteamLoadedBuildPartition(string targetFrameworkMoniker, string cliPath, string packagesPath, string runtimeFrameworkVersion, bool isNetCore)
Expand Down

0 comments on commit 6906de3

Please sign in to comment.