1
- using System . Reflection ;
2
- using BenchmarkDotNet . Columns ;
1
+ using BenchmarkDotNet . Columns ;
3
2
using BenchmarkDotNet . Jobs ;
3
+ using System . Text ;
4
+ using System . Text . Json . Nodes ;
4
5
5
6
namespace Benchmark ;
6
7
7
8
/// <summary>
8
- /// BenchmarkConfig.
9
+ /// BenchmarkConfig that run benchmarks to compare performance between LocalBuild/NuGet version .
9
10
/// </summary>
10
11
public class NuGetVersionsBenchmarkConfig : BaseBenchmarkConfig
11
12
{
@@ -15,27 +16,35 @@ public NuGetVersionsBenchmarkConfig() : base()
15
16
. WithToolchain ( Constants . DefaultToolchain )
16
17
. Freeze ( ) ;
17
18
19
+ string [ ] targetNuGetVersions = [ GetCurrentZLinqVersion ( ) ] ;
20
+
21
+ // Note: Enable following code when comparing multiple ZLinq versions.
22
+ // targetNuGetVersions = GetTargetZlinqVersions();
23
+
18
24
// 1. Add jobs that use ZLinq NuGet package with specified versions
19
- var targetNugetVersions = GetTargetNuGetVersions ( ) ;
20
- foreach ( var targetVersion in targetNugetVersions )
25
+ foreach ( var targetVersion in targetNuGetVersions )
21
26
{
22
27
var job = baseJobConfig
23
- . WithArguments ( [
24
- new MsBuildArgument ( "/p:UseZLinqNuGetPackage=true" ) ,
25
- new MsBuildArgument ( "/p:DefineConstants=" + $ "ZLinq_{ targetVersion . Replace ( '.' , '_' ) } ") ,
26
- ] )
27
- . WithNuGet ( "ZLinq" , targetVersion )
28
+ . WithCustomBuildConfiguration ( GetCustomBuildConfigurationName ( targetVersion ) )
29
+ . WithArguments (
30
+ [
31
+ new MsBuildArgument ( $ "/p:{ Constants . MSBuildProperties . TargetZLinqVersion } ={ targetVersion } ") ,
32
+ new MsBuildArgument ( $ "/p:{ Constants . MSBuildProperties . ZLinqDefineConstants } ={ GetDefineConstantsValue ( targetVersion ) } ") ,
33
+ // TODO: Enable following code and remove settings from csproj after .NET SDK issue is resolved. See:https://github.com/dotnet/sdk/issues/45638
34
+ // new MsBuildArgument($"/p:DefineConstants={GetDefineConstantsValue(targetVersion)}"),
35
+ ] )
28
36
. WithId ( $ "v{ targetVersion } ") ;
29
37
30
- bool isBaseline = targetVersion == targetNugetVersions . First ( ) ;
38
+ bool isBaseline = targetVersion == targetNuGetVersions . First ( ) ;
31
39
if ( isBaseline )
32
40
AddJob ( job . AsBaseline ( ) ) ;
33
41
else
34
42
AddJob ( job ) ;
35
43
}
36
44
37
- // 2. Add local build job.
38
- AddJob ( baseJobConfig . WithId ( "vLocalBuild" ) ) ; // Add `v` prefix to change display order.
45
+ // 2. Add LocalBuild job.
46
+ if ( targetNuGetVersions . Length == 1 )
47
+ AddJob ( baseJobConfig . WithId ( "vLocalBuild" ) ) ; // Add `v` prefix to change display order.
39
48
40
49
// Configure additional settings
41
50
AddConfigurations ( ) ;
@@ -45,16 +54,86 @@ protected override void AddColumnHidingRules()
45
54
{
46
55
HideColumns ( Column . Arguments ) ;
47
56
HideColumns ( Column . NuGetReferences ) ;
57
+ HideColumns ( Column . BuildConfiguration ) ;
58
+ }
59
+
60
+ /// <summary>
61
+ /// Gets DefineConstants settings for using target ZLinq version.
62
+ /// </summary>
63
+ private static string GetDefineConstantsValue ( string versionText )
64
+ {
65
+ // Currently it need to escape MSBuild special characters (https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-special-characters)
66
+ // Because MSBuildArgument is passed as commandline parameter.
67
+ // See: https://github.com/dotnet/BenchmarkDotNet/issues/2719
68
+ const string ListSeparator = "%3B" ; // Escapec semicolon char.
69
+
70
+ StringBuilder sb = new ( ) ;
71
+
72
+ // Add target package version symbol
73
+ sb . Append ( $ "{ ListSeparator } ZLINQ_{ versionText . Replace ( '.' , '_' ) } ") ;
74
+
75
+ // v1.2.0 or later supports Immutable/Frozen collection.
76
+ var version = Version . Parse ( versionText ) ;
77
+ if ( version >= new Version ( 1 , 2 , 0 ) )
78
+ sb . Append ( $ "{ ListSeparator } { Constants . DefineConstants . ZLINQ_1_2_0_OR_GREATER } ") ;
79
+
80
+ // v1.3.1 contains following breaking changes
81
+ // - WhereArray signature is changed to ArrayWhere.
82
+ // - ArraySelect/ListSelect optimization for Select from Array.
83
+ if ( version >= new Version ( 1 , 3 , 1 ) )
84
+ sb . Append ( $ "{ ListSeparator } { Constants . DefineConstants . ZLINQ_1_3_1_OR_GREATER } ") ;
85
+
86
+ // v1.4.0 changes the return value of ToArrayPool to PooledArray<T>,
87
+ if ( version >= new Version ( 1 , 4 , 0 ) )
88
+ sb . Append ( $ "{ ListSeparator } { Constants . DefineConstants . ZLINQ_1_4_0_OR_GREATER } ") ;
89
+
90
+ return sb . ToString ( ) ;
91
+ }
92
+
93
+ private static string GetCurrentZLinqVersion ( )
94
+ {
95
+ DirectoryInfo ? dirInfo = new DirectoryInfo ( AppContext . BaseDirectory ) ;
96
+ while ( true )
97
+ {
98
+ if ( dirInfo . GetFiles ( ) . Any ( x => x . Name == "ZLinq.slnx" ) )
99
+ break ;
100
+
101
+ dirInfo = dirInfo . Parent ;
102
+ if ( dirInfo == null )
103
+ throw new FileNotFoundException ( "ZLinq.slnx is not found." ) ;
104
+ }
105
+
106
+ var solutionDir = dirInfo . FullName ;
107
+ var resolvedPath = Path . Combine ( solutionDir , "src/ZLinq.Unity/Assets/ZLinq.Unity/package.json" ) ;
108
+ if ( ! File . Exists ( resolvedPath ) && ! Directory . Exists ( resolvedPath ) )
109
+ throw new FileNotFoundException ( $ "File is not found. path: { resolvedPath } ") ;
110
+
111
+ var json = File . ReadAllText ( resolvedPath ) ;
112
+ var latestVersion = JsonNode . Parse ( json ) ! [ "version" ] ! . GetValue < string > ( ) ;
113
+ return latestVersion ;
48
114
}
49
115
50
- private static string [ ] GetTargetNuGetVersions ( )
116
+ private static string [ ] GetTargetZlinqVersions ( )
51
117
{
52
- var assembly = Assembly . GetExecutingAssembly ( ) ;
53
- var assemblyMetadata = assembly . GetCustomAttributes < AssemblyMetadataAttribute > ( )
54
- . First ( x => x . Key == "TargetZLinqVersions" )
55
- . Value ! ;
118
+ // Currently multi NuGet versions benchmark is not supported.
119
+ // It require following BenchmarkDotNet feature.
120
+ // https://github.com/dotnet/BenchmarkDotNet/pull/2676
121
+ throw new NotSupportedException ( "Currently multi NuGet versions benchmark is not supported." ) ;
56
122
57
- return assemblyMetadata . Split ( ';' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries )
58
- . ToArray ( ) ;
123
+ // Available package versions: https://api.nuget.org/v3-flatcontainer/ZLinq/index.json
124
+ ////return
125
+ ////[
126
+ //// "1.0.0",
127
+ //// "1.1.0",
128
+ //// "1.2.0",
129
+ //// "1.3.0",
130
+ //// "1.3.1",
131
+ //// "1.4.0",
132
+ //// "1.4.1",
133
+ //// "1.4.2",
134
+ ////];
59
135
}
136
+
137
+ private static string GetCustomBuildConfigurationName ( string targetVersion )
138
+ => $ "{ Constants . CustomBuildConfigurations . UseZLinqNuGetPackage } _{ targetVersion . Replace ( "." , "_" ) } ";
60
139
}
0 commit comments