Skip to content

Commit

Permalink
Merge pull request dotnet#7052 from drewnoakes/dev/drnoakes/globbing-…
Browse files Browse the repository at this point in the history
…perf-2

Remove closure allocation in CompositeGlob.IsMatch
  • Loading branch information
rainersigwald authored Nov 22, 2021
2 parents 3bb10b7 + b623b1e commit 4d3ff70
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/Build/Globbing/CompositeGlob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ public class CompositeGlob : IMSBuildGlob
/// </summary>
/// <param name="globs">Children globs. Input gets shallow cloned</param>
public CompositeGlob(IEnumerable<IMSBuildGlob> globs)
: this(globs is ImmutableArray<IMSBuildGlob> immutableGlobs ? immutableGlobs : globs.ToImmutableArray())
: this(globs.ToImmutableArray())
{}

/// <summary>
/// Constructor
/// </summary>
/// <param name="globs">Children globs. Input gets shallow cloned</param>
public CompositeGlob(params IMSBuildGlob[] globs) : this(globs.ToImmutableArray())
public CompositeGlob(params IMSBuildGlob[] globs)
: this(ImmutableArray.Create(globs))
{}

/// <summary>
Expand All @@ -61,7 +62,7 @@ public bool IsMatch(string stringToMatch)
// Threadpools are a scarce resource in Visual Studio, do not use them.
//return Globs.AsParallel().Any(g => g.IsMatch(stringToMatch));

return _globs.Any(g => g.IsMatch(stringToMatch));
return _globs.Any(static (glob, str) => glob.IsMatch(str), stringToMatch);
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/Build/Microsoft.Build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
<Compile Include="BackEnd\Components\SdkResolution\SdkResolverException.cs" />
<Compile Include="BackEnd\Components\SdkResolution\TranslationHelpers.cs" />
<Compile Include="FileSystem\*.cs" />
<Compile Include="Utilities\ImmutableCollectionsExtensions.cs" />
<Compile Include="Utilities\NuGetFrameworkWrapper.cs" />
<Compile Include="ObjectModelRemoting\ConstructionObjectLinks\ProjectUsingTaskParameterElementLink.cs" />
<Compile Include="ObjectModelRemoting\ExternalProjectsProvider.cs" />
Expand Down
40 changes: 40 additions & 0 deletions src/Build/Utilities/ImmutableCollectionsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Immutable;

// Added to the System.Linq extension method as these extensions augment those
// provided by Linq. The immutable collections library includes ImmutableArrayExtensions
// which is also in this namespace.

namespace System.Linq
{
internal static class ImmutableCollectionsExtensions
{
/// <summary>
/// Gets a value indicating whether any elements are in this collection
/// that match a given condition.
/// </summary>
/// <remarks>
/// This extension method accepts an argument which is then passed, on the stack, to the predicate.
/// This allows using a static lambda, which can avoid a per-call allocation of a closure object.
/// </remarks>
/// <typeparam name="TElement">The type of element contained by the collection.</typeparam>
/// <typeparam name="TArg">The type of argument passed to <paramref name="predicate"/>.</typeparam>
/// <param name="immutableArray">The array to check.</param>
/// <param name="predicate">The predicate.</param>
/// <param name="arg">The argument to pass to <paramref name="predicate"/>.</param>
public static bool Any<TElement, TArg>(this ImmutableArray<TElement> immutableArray, Func<TElement, TArg, bool> predicate, TArg arg)
{
foreach (TElement element in immutableArray)
{
if (predicate(element, arg))
{
return true;
}
}

return false;
}
}
}

0 comments on commit 4d3ff70

Please sign in to comment.