From c5dbdc246575676bcde8bc73da854d654af087e5 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Fri, 9 Jun 2023 16:47:16 +1000 Subject: [PATCH 1/5] Stop resizing a list --- .../DefaultRazorTagHelperContextDiscoveryPhase.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs index 6962221338b..ea11ac51d20 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs @@ -5,11 +5,12 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; -using System.Linq; using Microsoft.AspNetCore.Razor.Language.Components; using Microsoft.AspNetCore.Razor.Language.Legacy; using Microsoft.AspNetCore.Razor.Language.Syntax; +using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.AspNetCore.Razor.Language; @@ -216,7 +217,7 @@ private bool AssemblyContainsTagHelpers(string assemblyName, IReadOnlyList _notFullyQualifiedComponents; + private readonly ImmutableArray _notFullyQualifiedComponents; private readonly string _filePath; private RazorSourceDocument _source; @@ -224,6 +225,9 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList.GetPooledObject(out var builder); + builder.SetCapacityIfNeeded(tagHelpers.Count); + for (var i = 0; i < tagHelpers.Count; i++) { var tagHelper = tagHelpers[i]; @@ -240,8 +244,7 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList Matches { get; } = new HashSet(); @@ -324,7 +329,7 @@ public override void VisitRazorDirective(RazorDirectiveSyntax node) continue; } - for (var i = 0; _notFullyQualifiedComponents is not null && i < _notFullyQualifiedComponents.Count; i++) + for (var i = 0; i < _notFullyQualifiedComponents.Length; i++) { var tagHelper = _notFullyQualifiedComponents[i]; Debug.Assert(!tagHelper.IsComponentFullyQualifiedNameMatch(), "We've already processed these."); From 64c1ea0fda930c35fd29ce827f3c8b92d2eb046a Mon Sep 17 00:00:00 2001 From: David Wengier Date: Sat, 10 Jun 2023 14:37:46 +1000 Subject: [PATCH 2/5] Allow passing in an initial capacity --- .../PooledObjects/PooledArrayBuilder`1.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs index 70956c2b8c3..ac1834a8c42 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs @@ -16,15 +16,17 @@ namespace Microsoft.AspNetCore.Razor.PooledObjects; internal ref struct PooledArrayBuilder { private readonly ObjectPool.Builder> _pool; + private readonly int? _capacity; private ImmutableArray.Builder? _builder; - public PooledArrayBuilder() - : this(ArrayBuilderPool.Default) + public PooledArrayBuilder(int? capacity = null) + : this(ArrayBuilderPool.Default, capacity) { } - public PooledArrayBuilder(ObjectPool.Builder> pool) + public PooledArrayBuilder(ObjectPool.Builder> pool, int? capacity = null) { + _capacity = capacity; _pool = pool; } @@ -38,10 +40,11 @@ public readonly int Count public void Add(T item) { - _builder ??= _pool.Get(); + _builder ??= CreateBuilder(); _builder.Add(item); } + public void AddRange(IReadOnlyList items) { if (items.Count == 0) @@ -49,13 +52,13 @@ public void AddRange(IReadOnlyList items) return; } - _builder ??= _pool.Get(); + _builder ??= CreateBuilder(); _builder.AddRange(items); } public void AddRange(IEnumerable items) { - _builder ??= _pool.Get(); + _builder ??= CreateBuilder(); _builder.AddRange(items); } @@ -68,6 +71,16 @@ public void ClearAndFree() } } + private readonly ImmutableArray.Builder CreateBuilder() + { + var result = _pool.Get(); + if (_capacity.HasValue) + { + result.SetCapacityIfNeeded(_capacity.Value); + } + return result; + } + /// /// Returns the current contents as an and sets /// the collection to a zero length array. From 23a066ccd2fb56e8765b28e3b82d058fb76d14c5 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Sat, 10 Jun 2023 14:37:51 +1000 Subject: [PATCH 3/5] PR Feedback --- .../src/DefaultRazorTagHelperContextDiscoveryPhase.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs index ea11ac51d20..73276cdaa1f 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs @@ -225,8 +225,7 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList.GetPooledObject(out var builder); - builder.SetCapacityIfNeeded(tagHelpers.Count); + using var builder = new PooledArrayBuilder(tagHelpers.Count); for (var i = 0; i < tagHelpers.Count; i++) { @@ -267,7 +266,7 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList Matches { get; } = new HashSet(); @@ -329,9 +328,8 @@ public override void VisitRazorDirective(RazorDirectiveSyntax node) continue; } - for (var i = 0; i < _notFullyQualifiedComponents.Length; i++) + foreach (var tagHelper in _notFullyQualifiedComponents) { - var tagHelper = _notFullyQualifiedComponents[i]; Debug.Assert(!tagHelper.IsComponentFullyQualifiedNameMatch(), "We've already processed these."); if (tagHelper.IsChildContentTagHelper()) From 6578411445d8a6e01875636ac7bb93d9e07c26ab Mon Sep 17 00:00:00 2001 From: David Wengier Date: Sat, 10 Jun 2023 15:12:46 +1000 Subject: [PATCH 4/5] Better constructors --- .../src/DefaultRazorTagHelperContextDiscoveryPhase.cs | 2 +- .../PooledObjects/PooledArrayBuilder`1.cs | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs index 73276cdaa1f..b4e3d8ec2eb 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorTagHelperContextDiscoveryPhase.cs @@ -225,7 +225,7 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList(tagHelpers.Count); + using var builder = new PooledArrayBuilder(capacity: tagHelpers.Count); for (var i = 0; i < tagHelpers.Count; i++) { diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs index ac1834a8c42..b2399464394 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs @@ -19,15 +19,15 @@ internal ref struct PooledArrayBuilder private readonly int? _capacity; private ImmutableArray.Builder? _builder; - public PooledArrayBuilder(int? capacity = null) - : this(ArrayBuilderPool.Default, capacity) + public PooledArrayBuilder() + :this(null, null) { } - public PooledArrayBuilder(ObjectPool.Builder> pool, int? capacity = null) + public PooledArrayBuilder(ObjectPool.Builder>? pool = null, int? capacity = null) { + _pool = pool ?? ArrayBuilderPool.Default; _capacity = capacity; - _pool = pool; } public void Dispose() @@ -44,7 +44,6 @@ public void Add(T item) _builder.Add(item); } - public void AddRange(IReadOnlyList items) { if (items.Count == 0) @@ -73,7 +72,7 @@ public void ClearAndFree() private readonly ImmutableArray.Builder CreateBuilder() { - var result = _pool.Get(); + var result = _pool.Get(); if (_capacity.HasValue) { result.SetCapacityIfNeeded(_capacity.Value); From c55d54c623e4c1980414141b0f4c5fbdcf7f37ab Mon Sep 17 00:00:00 2001 From: David Wengier Date: Tue, 13 Jun 2023 08:34:49 +1000 Subject: [PATCH 5/5] PR feedback --- .../PooledObjects/PooledArrayBuilder`1.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs index b2399464394..b88dda7d0e8 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/PooledObjects/PooledArrayBuilder`1.cs @@ -20,7 +20,7 @@ internal ref struct PooledArrayBuilder private ImmutableArray.Builder? _builder; public PooledArrayBuilder() - :this(null, null) + : this(null, null) { } @@ -40,7 +40,7 @@ public readonly int Count public void Add(T item) { - _builder ??= CreateBuilder(); + _builder ??= GetBuilder(); _builder.Add(item); } @@ -51,13 +51,13 @@ public void AddRange(IReadOnlyList items) return; } - _builder ??= CreateBuilder(); + _builder ??= GetBuilder(); _builder.AddRange(items); } public void AddRange(IEnumerable items) { - _builder ??= CreateBuilder(); + _builder ??= GetBuilder(); _builder.AddRange(items); } @@ -70,13 +70,14 @@ public void ClearAndFree() } } - private readonly ImmutableArray.Builder CreateBuilder() + private readonly ImmutableArray.Builder GetBuilder() { var result = _pool.Get(); - if (_capacity.HasValue) + if (_capacity is int capacity) { - result.SetCapacityIfNeeded(_capacity.Value); + result.SetCapacityIfNeeded(capacity); } + return result; }