Skip to content

Commit 3aad478

Browse files
committed
Reduced a memory allocation by using collection expressions
1 parent 88db4ac commit 3aad478

16 files changed

+143
-44
lines changed

src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.ScriptSiteBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ private string GetDocumentName(uint sourceContext)
187187
/// <returns>An array of <see cref="CallStackItem"/> instances</returns>
188188
protected virtual CallStackItem[] GetCallStackItems()
189189
{
190-
return new CallStackItem[0];
190+
return [];
191191
}
192192

193193
#region IActiveScriptSite implementation

src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ private object InnerGetVariableValue(string variableName)
479479
try
480480
{
481481
variableValue = _dispatch.InvokeMember(variableName, BindingFlags.GetProperty,
482-
null, _dispatch, new object[0], null,
482+
null, _dispatch, [], null,
483483
CultureInfo.InvariantCulture, null);
484484
}
485485
catch

src/MsieJavaScriptEngine/ActiveScript/HostItemBase.cs

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
#if NETFRAMEWORK
22
using System;
3+
#if NET45_OR_GREATER
4+
using System.Buffers;
5+
#endif
36
using System.Globalization;
47
using System.Reflection;
8+
#if NET40
9+
10+
using PolyfillsForOldDotNet.System.Buffers;
11+
#endif
512

613
using MsieJavaScriptEngine.Helpers;
714

@@ -93,42 +100,92 @@ protected HostItemBase(Type type, object target, JsEngineMode engineMode, bool a
93100
private static PropertyInfo[] GetAvailableProperties(PropertyInfo[] properties)
94101
{
95102
int propertyCount = properties.Length;
96-
var availableProperties = new PropertyInfo[propertyCount];
97-
int availablePropertyIndex = 0;
103+
PropertyInfo[] availableProperties = null;
104+
int availablePropertyCount = 0;
105+
106+
var propertyArrayPool = ArrayPool<PropertyInfo>.Shared;
107+
PropertyInfo[] buffer = propertyArrayPool.Rent(propertyCount);
98108

99-
for (int propertyIndex = 0; propertyIndex < propertyCount; propertyIndex++)
109+
try
100110
{
101-
PropertyInfo property = properties[propertyIndex];
102-
if (ReflectionHelpers.IsAllowedProperty(property))
111+
foreach (PropertyInfo property in properties)
103112
{
104-
availableProperties[availablePropertyIndex] = property;
105-
availablePropertyIndex++;
113+
if (ReflectionHelpers.IsAllowedProperty(property))
114+
{
115+
availablePropertyCount++;
116+
117+
int availablePropertyIndex = availablePropertyCount - 1;
118+
buffer[availablePropertyIndex] = property;
119+
}
106120
}
107-
}
108121

109-
Array.Resize(ref availableProperties, availablePropertyIndex);
122+
if (availablePropertyCount < propertyCount)
123+
{
124+
if (availablePropertyCount == 0)
125+
{
126+
return [];
127+
}
128+
129+
availableProperties = new PropertyInfo[availablePropertyCount];
130+
Array.Copy(buffer, availableProperties, availablePropertyCount);
131+
}
132+
else
133+
{
134+
availableProperties = properties;
135+
}
136+
}
137+
finally
138+
{
139+
bool clearArray = availablePropertyCount > 0;
140+
propertyArrayPool.Return(buffer, clearArray);
141+
}
110142

111143
return availableProperties;
112144
}
113145

114146
private static MethodInfo[] GetAvailableMethods(MethodInfo[] methods, bool allowReflection)
115147
{
116148
int methodCount = methods.Length;
117-
var availableMethods = new MethodInfo[methodCount];
118-
int availableMethodIndex = 0;
149+
MethodInfo[] availableMethods = null;
150+
int availableMethodCount = 0;
151+
152+
var methodArrayPool = ArrayPool<MethodInfo>.Shared;
153+
MethodInfo[] buffer = methodArrayPool.Rent(methodCount);
119154

120-
for (int methodIndex = 0; methodIndex < methodCount; methodIndex++)
155+
try
121156
{
122-
MethodInfo method = methods[methodIndex];
123-
if (ReflectionHelpers.IsFullyFledgedMethod(method)
124-
&& (allowReflection || ReflectionHelpers.IsAllowedMethod(method)))
157+
foreach (MethodInfo method in methods)
125158
{
126-
availableMethods[availableMethodIndex] = method;
127-
availableMethodIndex++;
159+
if (ReflectionHelpers.IsFullyFledgedMethod(method)
160+
&& (allowReflection || ReflectionHelpers.IsAllowedMethod(method)))
161+
{
162+
availableMethodCount++;
163+
164+
int availableMethodIndex = availableMethodCount - 1;
165+
buffer[availableMethodIndex] = method;
166+
}
128167
}
129-
}
130168

131-
Array.Resize(ref availableMethods, availableMethodIndex);
169+
if (availableMethodCount < methodCount)
170+
{
171+
if (availableMethodCount == 0)
172+
{
173+
return [];
174+
}
175+
176+
availableMethods = new MethodInfo[availableMethodCount];
177+
Array.Copy(buffer, availableMethods, availableMethodCount);
178+
}
179+
else
180+
{
181+
availableMethods = methods;
182+
}
183+
}
184+
finally
185+
{
186+
bool clearArray = availableMethodCount > 0;
187+
methodArrayPool.Return(buffer, clearArray);
188+
}
132189

133190
return availableMethods;
134191
}

src/MsieJavaScriptEngine/ActiveScript/HostObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ protected override object InnerInvokeMember(string name, BindingFlags invokeAttr
7676
}
7777
else
7878
{
79-
processedArgs = new object[0];
79+
processedArgs = [];
8080
}
8181

8282
result = del.DynamicInvoke(processedArgs);

src/MsieJavaScriptEngine/Extensions/StringExtensions.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
using System;
22

3+
using MsieJavaScriptEngine.Utilities;
4+
35
namespace MsieJavaScriptEngine.Extensions
46
{
57
/// <summary>
68
/// Extensions for String
79
/// </summary>
810
internal static class StringExtensions
911
{
12+
/// <summary>
13+
/// Array of strings used to find the newline
14+
/// </summary>
15+
private static readonly string[] _newLineStrings = ["\r\n", "\r", "\n"];
16+
17+
1018
/// <summary>
1119
/// Returns a value indicating whether the specified quoted string occurs within this string
1220
/// </summary>
@@ -62,6 +70,25 @@ public static string TrimStart(this string source, string trimString)
6270

6371
return result;
6472
}
73+
74+
/// <summary>
75+
/// Removes all leading newline characters from the current <see cref="T:System.String" /> object
76+
/// </summary>
77+
/// <param name="source">String value</param>
78+
/// <returns>The string that remains after all newline characters are removed from the start of
79+
/// the current string. If no characters can be trimmed from the current instance, the method returns
80+
/// the current instance unchanged.</returns>
81+
public static string TrimStartNewLines(this string source)
82+
{
83+
if (source is null)
84+
{
85+
throw new ArgumentNullException(nameof(source));
86+
}
87+
88+
string result = source.TrimStart(EnvironmentShortcuts.NewLineChars);
89+
90+
return result;
91+
}
6592
#if NETFRAMEWORK
6693

6794
/// <summary>
@@ -114,7 +141,7 @@ public static string[] SplitToLines(this string source)
114141
throw new ArgumentNullException(nameof(source));
115142
}
116143

117-
string[] result = source.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
144+
string[] result = source.Split(_newLineStrings, StringSplitOptions.None);
118145

119146
return result;
120147
}

src/MsieJavaScriptEngine/Helpers/JsErrorHelpers.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ internal static CallStackItem[] ParseCallStack(string callStack)
3838
{
3939
if (string.IsNullOrWhiteSpace(callStack))
4040
{
41-
return new CallStackItem[0];
41+
return [];
4242
}
4343

44-
var callStackItems = new List<CallStackItem>();
4544
string[] lines = callStack.SplitToLines();
4645
int lineCount = lines.Length;
46+
var callStackItems = new List<CallStackItem>(lineCount);
4747

4848
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++)
4949
{
@@ -66,7 +66,7 @@ internal static CallStackItem[] ParseCallStack(string callStack)
6666
else
6767
{
6868
Debug.WriteLine(string.Format(CommonStrings.Runtime_InvalidCallStackLineFormat, line));
69-
return new CallStackItem[0];
69+
return [];
7070
}
7171
}
7272

src/MsieJavaScriptEngine/Helpers/ReflectionHelpers.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,8 @@ public static MethodBase GetBestFitMethod(MethodBase[] methods, object[] argValu
187187

188188
try
189189
{
190-
for (int methodIndex = 0; methodIndex < methodCount; methodIndex++)
190+
foreach (MethodBase method in methods)
191191
{
192-
MethodBase method = methods[methodIndex];
193192
ParameterInfo[] parameters = method.GetParameters();
194193
ushort compatibilityScore;
195194

src/MsieJavaScriptEngine/Helpers/TextHelpers.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using AdvancedStringBuilder;
55

66
using MsieJavaScriptEngine.Extensions;
7+
using MsieJavaScriptEngine.Utilities;
78

89
namespace MsieJavaScriptEngine.Helpers
910
{
@@ -15,7 +16,7 @@ internal static class TextHelpers
1516
/// <summary>
1617
/// Array of characters used to find the next line break
1718
/// </summary>
18-
private static readonly char[] _nextLineBreakChars = new char[] { '\r', '\n' };
19+
private static readonly char[] _nextLineBreakChars = EnvironmentShortcuts.NewLineChars;
1920

2021

2122
/// <summary>

src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ private WrapperException WrapJsException(OriginalException originalException,
283283
string rawCallStack = messageWithTypeAndCallStack
284284
.TrimStart(messageWithType)
285285
.TrimStart("Error")
286-
.TrimStart(new char[] { '\n', '\r' })
286+
.TrimStartNewLines()
287287
;
288288

289289
CallStackItem[] callStackItems = JsErrorHelpers.ParseCallStack(rawCallStack);

src/MsieJavaScriptEngine/JsRt/Edge/EdgeTypeMapper.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,7 @@ private EdgeEmbeddedObject CreateEmbeddedFunction(Delegate del)
206206
EdgeJsValue functionValue = EdgeJsValue.CreateFunction(nativeFunction);
207207
SetNonEnumerableProperty(functionValue, ExternalObjectPropertyName, objValue);
208208

209-
var embeddedObject = new EdgeEmbeddedObject(del, functionValue,
210-
new List<EdgeJsNativeFunction> { nativeFunction });
209+
var embeddedObject = new EdgeEmbeddedObject(del, functionValue, [nativeFunction]);
211210

212211
return embeddedObject;
213212
}
@@ -466,7 +465,7 @@ private void ProjectProperties(EdgeEmbeddedItem externalItem)
466465

467466
try
468467
{
469-
result = property.GetValue(obj, new object[0]);
468+
result = property.GetValue(obj, []);
470469
}
471470
catch (Exception e)
472471
{
@@ -522,7 +521,7 @@ private void ProjectProperties(EdgeEmbeddedItem externalItem)
522521

523522
try
524523
{
525-
property.SetValue(obj, value, new object[0]);
524+
property.SetValue(obj, value, []);
526525
}
527526
catch (Exception e)
528527
{

0 commit comments

Comments
 (0)