Skip to content

Commit 3725e24

Browse files
eerhardtjozkee
andauthored
Reduce Linq usage in FileSystemGlobbing (#98109)
* Reduce Linq usage in FileSystemGlobbing Since GetResultsInFullPath uses a struct (FilePatternMatch) in a Linq call, this is causing extra disk space on native AOT'd applications because of struct specialization. Remove the Linq call and instead use a simple loop to create the result. * Use ToArray instead of ToList to reduce unnecessary allocations. --------- Co-authored-by: David Cantú <[email protected]>
1 parent 478ab30 commit 3725e24

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal
1717
public class MatcherContext
1818
{
1919
private readonly DirectoryInfoBase _root;
20-
private readonly List<IPatternContext> _includePatternContexts;
21-
private readonly List<IPatternContext> _excludePatternContexts;
20+
private readonly IPatternContext[] _includePatternContexts;
21+
private readonly IPatternContext[] _excludePatternContexts;
2222
private readonly List<FilePatternMatch> _files;
2323

2424
private readonly HashSet<string> _declaredLiteralFolderSegmentInString;
@@ -39,8 +39,8 @@ public MatcherContext(
3939
_files = new List<FilePatternMatch>();
4040
_comparisonType = comparison;
4141

42-
_includePatternContexts = includePatterns.Select(pattern => pattern.CreatePatternContextForInclude()).ToList();
43-
_excludePatternContexts = excludePatterns.Select(pattern => pattern.CreatePatternContextForExclude()).ToList();
42+
_includePatternContexts = includePatterns.Select(pattern => pattern.CreatePatternContextForInclude()).ToArray();
43+
_excludePatternContexts = excludePatterns.Select(pattern => pattern.CreatePatternContextForExclude()).ToArray();
4444

4545
_declaredLiteralFolderSegmentInString = new HashSet<string>(StringComparisonHelper.GetStringComparer(comparison));
4646
}
@@ -67,10 +67,11 @@ private void Match(DirectoryInfoBase directory, string? parentRelativePath)
6767
}
6868
else
6969
{
70-
IEnumerable<DirectoryInfoBase> candidates = directory.EnumerateFileSystemInfos().OfType<DirectoryInfoBase>();
71-
foreach (DirectoryInfoBase candidate in candidates)
70+
IEnumerable<FileSystemInfoBase> candidates = directory.EnumerateFileSystemInfos();
71+
foreach (FileSystemInfoBase candidate in candidates)
7272
{
73-
if (_declaredLiteralFolderSegmentInString.Contains(candidate.Name))
73+
if (candidate is DirectoryInfoBase &&
74+
_declaredLiteralFolderSegmentInString.Contains(candidate.Name))
7475
{
7576
entities.Add(candidate);
7677
}

src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Collections;
56
using System.Collections.Generic;
67
using System.IO;
7-
using System.Linq;
88
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
99

1010
namespace Microsoft.Extensions.FileSystemGlobbing
@@ -51,9 +51,18 @@ public static void AddIncludePatterns(this Matcher matcher, params IEnumerable<s
5151
/// <returns>Absolute file paths of all files matched. Empty enumerable if no files matched given patterns.</returns>
5252
public static IEnumerable<string> GetResultsInFullPath(this Matcher matcher, string directoryPath)
5353
{
54-
IEnumerable<FilePatternMatch> matches = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath))).Files;
55-
string[] result = matches.Select(match => Path.GetFullPath(Path.Combine(directoryPath, match.Path))).ToArray();
54+
PatternMatchingResult patternMatchingResult = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directoryPath)));
55+
if (!patternMatchingResult.HasMatches)
56+
{
57+
return Array.Empty<string>();
58+
}
5659

60+
IEnumerable<FilePatternMatch> matches = patternMatchingResult.Files;
61+
List<string> result = matches is ICollection matchCollection ? new(matchCollection.Count) : new();
62+
foreach (FilePatternMatch match in matches)
63+
{
64+
result.Add(Path.GetFullPath(Path.Combine(directoryPath, match.Path)));
65+
}
5766
return result;
5867
}
5968

0 commit comments

Comments
 (0)