Skip to content

Commit e8ad645

Browse files
#136 Insufficient performance 4
1 parent a1439fc commit e8ad645

1 file changed

Lines changed: 41 additions & 23 deletions

File tree

src/Pure.DI.Core/Core/Code/VarsMap.cs

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class VarsMap(
1212
: IVarsMap
1313
{
1414
private readonly Dictionary<int, Var> _map = [];
15+
private static readonly IReadOnlyDictionary<int, VarState> EmptyState = new Dictionary<int, VarState>();
1516

1617
/// <inheritdoc />
1718
public IEnumerable<Var> Vars => _map.Values;
@@ -101,7 +102,7 @@ public IDisposable LocalFunction(Var var, Lines lines)
101102
var state = CreateState(var);
102103

103104
// Per-block variables should be isolated between local functions.
104-
var removed = new List<KeyValuePair<int, Var>>();
105+
List<KeyValuePair<int, Var>>? removed = null;
105106
foreach (var item in _map)
106107
{
107108
if (item.Value.AbstractNode.ActualLifetime is not Lifetime.PerBlock)
@@ -112,18 +113,26 @@ public IDisposable LocalFunction(Var var, Lines lines)
112113
#if DEBUG
113114
lines.AppendLine($"// {item.Value.Declaration.Name}: remove ({nameof(LocalFunction)})");
114115
#endif
115-
removed.Add(item);
116+
(removed ??= []).Add(item);
116117
}
117118

118-
foreach (var item in removed)
119+
if (removed is not null)
119120
{
120-
_map.Remove(item.Key);
121+
foreach (var item in removed)
122+
{
123+
_map.Remove(item.Key);
124+
}
121125
}
122126

123127
return Disposables.Create(() => {
124128
// Cleanup and restore state after exiting the local function.
125129
RemoveNewNonPersistentVars(var, state, lines, nameof(LocalFunction));
126130
RestoreState(var, state, lines, nameof(LocalFunction), false);
131+
if (removed is null)
132+
{
133+
return;
134+
}
135+
127136
foreach (var item in removed)
128137
{
129138
#if DEBUG
@@ -184,10 +193,10 @@ node.ActualLifetime is Lifetime.PerBlock
184193
/// Global code state (like LocalFunction) is NOT part of the snapshot because it should accumulate.
185194
/// Only path-specific state (IsDeclared, IsCreated, CodeExpression) is captured.
186195
/// </summary>
187-
private Dictionary<int, VarState> CreateState(Var var)
196+
private IReadOnlyDictionary<int, VarState> CreateState(Var var)
188197
{
189198
var excludeBindingId = var.AbstractNode.BindingId;
190-
var result = new Dictionary<int, VarState>(_map.Count);
199+
Dictionary<int, VarState>? result = null;
191200
foreach (var item in _map)
192201
{
193202
if (item.Key == excludeBindingId)
@@ -201,10 +210,10 @@ private Dictionary<int, VarState> CreateState(Var var)
201210
continue;
202211
}
203212

204-
result[item.Key] = new VarState(item.Value);
213+
(result ??= new Dictionary<int, VarState>(_map.Count))[item.Key] = new VarState(item.Value);
205214
}
206215

207-
return result;
216+
return result ?? EmptyState;
208217
}
209218

210219
/// <summary>
@@ -225,7 +234,7 @@ private void RemoveNewNonPersistentVars(Var var, IReadOnlyDictionary<int, VarSta
225234
return;
226235
}
227236

228-
var newItems = new List<KeyValuePair<int, Var>>();
237+
List<KeyValuePair<int, Var>>? newItems = null;
229238
foreach (var item in _map)
230239
{
231240
if (state.ContainsKey(item.Key))
@@ -239,18 +248,23 @@ private void RemoveNewNonPersistentVars(Var var, IReadOnlyDictionary<int, VarSta
239248
if (!IsNestedScopePersistentNode(node)
240249
&& !ShouldKeepCurrentNodeInNestedScope(node))
241250
{
242-
newItems.Add(item);
251+
(newItems ??= []).Add(item);
243252
}
244253

245254
continue;
246255
}
247256

248257
if (!IsNestedScopePersistentNode(node))
249258
{
250-
newItems.Add(item);
259+
(newItems ??= []).Add(item);
251260
}
252261
}
253262

263+
if (newItems is null)
264+
{
265+
return;
266+
}
267+
254268
foreach (var item in newItems)
255269
{
256270
#if DEBUG
@@ -337,21 +351,25 @@ private void RestoreState(Var var, IReadOnlyDictionary<int, VarState> state, Lin
337351
}
338352
}
339353

340-
private readonly record struct VarState(
341-
Var Var,
342-
bool IsDeclared,
343-
bool IsCreated,
344-
bool IsLocalFunctionCalled,
345-
string? RawCodeExpression)
354+
private readonly struct VarState
346355
{
356+
public readonly Var Var;
357+
358+
public readonly bool IsDeclared;
359+
360+
public readonly bool IsCreated;
361+
362+
public readonly bool IsLocalFunctionCalled;
363+
364+
public readonly string? RawCodeExpression;
365+
347366
public VarState(Var variable)
348-
: this(
349-
variable,
350-
variable.Declaration.IsDeclared,
351-
variable.IsCreated,
352-
variable.IsLocalFunctionCalled,
353-
variable.RawCodeExpression)
354367
{
368+
Var = variable;
369+
IsDeclared = variable.Declaration.IsDeclared;
370+
IsCreated = variable.IsCreated;
371+
IsLocalFunctionCalled = variable.IsLocalFunctionCalled;
372+
RawCodeExpression = variable.RawCodeExpression;
355373
}
356374
}
357375
}

0 commit comments

Comments
 (0)