From 0303d9682a52fb62791f8e60e09489e48c5d5f65 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 29 Apr 2021 08:38:57 -0600 Subject: [PATCH] Avoid an array copy and `List` allocation --- .../ManagedGit/GitRepository.cs | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/NerdBank.GitVersioning/ManagedGit/GitRepository.cs b/src/NerdBank.GitVersioning/ManagedGit/GitRepository.cs index e12f46fe..741ec25c 100644 --- a/src/NerdBank.GitVersioning/ManagedGit/GitRepository.cs +++ b/src/NerdBank.GitVersioning/ManagedGit/GitRepository.cs @@ -17,7 +17,7 @@ public class GitRepository : IDisposable { private const string HeadFileName = "HEAD"; private const string GitDirectoryName = ".git"; - private readonly Lazy packs; + private readonly Lazy> packs; /// /// UTF-16 encoded string. @@ -137,7 +137,7 @@ public GitRepository(string workingDirectory, string gitDirectory, string common this.objectPathBuffer[this.ObjectDirectory.Length + 3] = '/'; this.objectPathBuffer[pathLengthInChars - 1] = '\0'; // Make sure to initialize with zeros - this.packs = new Lazy(this.LoadPacks); + this.packs = new Lazy>(this.LoadPacks); } // TODO: read from Git settings @@ -375,7 +375,7 @@ public GitCommit GetCommit(GitObjectId sha, bool readAuthor = false) var hex = ConvertHexStringToByteArray(objectish); - foreach (var pack in this.packs.Value) + foreach (var pack in this.packs.Value.Span) { var objectId = pack.Lookup(hex, endsWithHalfByte); @@ -514,7 +514,7 @@ public bool TryGetObjectBySha(GitObjectId sha, string objectType, out Stream? va } #endif - foreach (var pack in this.packs.Value) + foreach (var pack in this.packs.Value.Span) { if (pack.TryGetObject(sha, objectType, out value)) { @@ -563,7 +563,7 @@ public string GetCacheStatistics() builder.AppendLine(); #endif - foreach (var pack in this.packs.Value) + foreach (var pack in this.packs.Value.Span) { pack.GetCacheStatistics(builder); } @@ -582,7 +582,7 @@ public void Dispose() { if (this.packs.IsValueCreated) { - foreach (var pack in this.packs.Value) + foreach (var pack in this.packs.Value.Span) { pack.Dispose(); } @@ -638,7 +638,7 @@ private GitObjectId ResolveReference(object reference) } } - private GitPack[] LoadPacks() + private ReadOnlyMemory LoadPacks() { var packDirectory = Path.Combine(this.ObjectDirectory, "pack/"); @@ -648,11 +648,11 @@ private GitPack[] LoadPacks() } var indexFiles = Directory.GetFiles(packDirectory, "*.idx"); - List packs = new List(indexFiles.Length); + var packs = new GitPack[indexFiles.Length]; + int addCount = 0; for (int i = 0; i < indexFiles.Length; i++) { - var name = Path.GetFileNameWithoutExtension(indexFiles[i]); var indexPath = Path.Combine(this.ObjectDirectory, "pack", $"{name}.idx"); var packPath = Path.Combine(this.ObjectDirectory, "pack", $"{name}.pack"); @@ -660,12 +660,11 @@ private GitPack[] LoadPacks() // Only proceed if both the packfile and index file exist. if (File.Exists(packPath)) { - packs.Add(new GitPack(this.GetObjectBySha, indexPath, packPath)); + packs[addCount++] = new GitPack(this.GetObjectBySha, indexPath, packPath); } - } - return packs.ToArray(); + return packs.AsMemory(0, addCount); } private static string TrimEndingDirectorySeparator(string path)