Skip to content

Commit

Permalink
[optimization] Replace 'new T[0]' with 'Array.Empty<T> ()' to reduce …
Browse files Browse the repository at this point in the history
…allocations. (#6162)

`Array.Empty` internally will cache types so that after the first use
remaining calls will use the cached version. This means we end up with
only 1 allocation for type rather than 1 allocation per instance.

Code in the future should use the `Array.Empty<T> ()` pattern rather than
the usual `new T[0]` which we use.

While this might seem like a small thing given the number of places we
use this, we should at least try to improve or performance where we can :)
  • Loading branch information
dellis1972 committed Aug 4, 2021
1 parent 60efd75 commit 550325a
Show file tree
Hide file tree
Showing 32 changed files with 236 additions and 234 deletions.
Expand Up @@ -45,7 +45,7 @@ public override bool Execute ()

if (LogTaskMessages) {
Log.LogMessage (MessageImportance.Low, $" [Output] {nameof (Output)}:");
foreach (var line in (Output ?? new string [0]))
foreach (var line in (Output ?? Array.Empty<string> ()))
Log.LogMessage (MessageImportance.Low, $" {line}");
}

Expand Down
Expand Up @@ -45,7 +45,7 @@ public override bool Execute ()

if (LogTaskMessages) {
Log.LogMessage (MessageImportance.Low, $" [Output] {nameof (Output)}:");
foreach (var line in (Output ?? new string [0]))
foreach (var line in (Output ?? Array.Empty<string> ()))
Log.LogMessage (MessageImportance.Low, $" {line}");
}

Expand Down
Expand Up @@ -49,7 +49,7 @@ public class RunInstrumentationTests : Adb

public override bool Execute ()
{
InstrumentationArguments = InstrumentationArguments ?? new string [0];
InstrumentationArguments = InstrumentationArguments ?? Array.Empty<string> ();
if (string.IsNullOrEmpty (NUnit2TestResultsFile)) {
var n = new StringBuilder ("TestResult-").Append (Component);
foreach (var c in Path.GetInvalidFileNameChars ()) {
Expand Down
Expand Up @@ -28,7 +28,7 @@ public override bool Execute ()
Log.LogMessage (MessageImportance.Low, $"Task {nameof (Zip)}");
Log.LogMessage (MessageImportance.Low, $" {nameof (File)}: {File.ItemSpec}");
Log.LogMessage (MessageImportance.Low, $" {nameof (Entries)}:");
foreach (var p in Entries ?? new ITaskItem [0]) {
foreach (var p in Entries ?? Array.Empty<ITaskItem> ()) {
Log.LogMessage (MessageImportance.Low, $" {p.ItemSpec}");
}
Log.LogMessage (MessageImportance.Low, $" {nameof (Overwrite)}: {Overwrite}");
Expand Down
36 changes: 18 additions & 18 deletions build-tools/api-merge/Mono.Options-PCL.cs
Expand Up @@ -18,10 +18,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -42,16 +42,16 @@
// A Getopt::Long-inspired option parsing library for C#.
//
// NDesk.Options.OptionSet is built upon a key/value table, where the
// key is a option format string and the value is a delegate that is
// key is a option format string and the value is a delegate that is
// invoked when the format string is matched.
//
// Option format strings:
// Regex-like BNF Grammar:
// Regex-like BNF Grammar:
// name: .+
// type: [=:]
// sep: ( [^{}]+ | '{' .+ '}' )?
// aliases: ( name type sep ) ( '|' name type sep )*
//
//
// Each '|'-delimited name is an alias for the associated action. If the
// format string ends in a '=', it has a required value. If the format
// string ends in a ':', it has an optional value. If neither '=' or ':'
Expand Down Expand Up @@ -97,7 +97,7 @@
// p.Parse (new string[]{"-v", "--v", "/v", "-name=A", "/name", "B", "extra"});
//
// The above would parse the argument string array, and would invoke the
// lambda expression three times, setting `verbose' to 3 when complete.
// lambda expression three times, setting `verbose' to 3 when complete.
// It would also print out "A" and "B" to standard output.
// The returned array would contain the string "extra".
//
Expand Down Expand Up @@ -364,7 +364,7 @@ private void AssertValid (int index)
if (c.Option.OptionValueType == OptionValueType.Required &&
index >= values.Count)
throw new OptionException (string.Format (
c.OptionSet.MessageLocalizer ("Missing required value for option '{0}'."), c.OptionName),
c.OptionSet.MessageLocalizer ("Missing required value for option '{0}'."), c.OptionName),
c.OptionName);
}

Expand Down Expand Up @@ -415,7 +415,7 @@ public OptionContext (OptionSet set)
set { option = value; }
}

public string OptionName {
public string OptionName {
get { return name; }
set { name = value; }
}
Expand Down Expand Up @@ -519,7 +519,7 @@ public string[] GetNames ()
public string[] GetValueSeparators ()
{
if (separators == null)
return new string [0];
return Array.Empty<string> ();
return (string[])separators.Clone ();
}

Expand Down Expand Up @@ -672,10 +672,10 @@ static IEnumerable<string> GetArguments (TextReader reader, bool close)

for (int i = 0; i < t; i++) {
char c = line [i];

if (c == '"' || c == '\'') {
char end = c;

for (i++; i < t; i++) {
c = line [i];

Expand Down Expand Up @@ -889,7 +889,7 @@ public OptionSet Add (string prototype, string description, Action<string> actio
{
if (action == null)
throw new ArgumentNullException ("action");
Option p = new ActionOption (prototype, description, 1,
Option p = new ActionOption (prototype, description, 1,
delegate (OptionValueCollection v) {
action (v [0]);
}, hidden);
Expand All @@ -911,7 +911,7 @@ public OptionSet Add (string prototype, string description, OptionAction<string,
{
if (action == null)
throw new ArgumentNullException ("action");
Option p = new ActionOption (prototype, description, 2,
Option p = new ActionOption (prototype, description, 2,
delegate (OptionValueCollection v) {
action (v [0], v [1]);
}, hidden);
Expand Down Expand Up @@ -1121,7 +1121,7 @@ protected virtual bool Parse (string argument, OptionContext c)
c.Option.Invoke (c);
break;
case OptionValueType.Optional:
case OptionValueType.Required:
case OptionValueType.Required:
ParseValue (v, c);
break;
}
Expand All @@ -1140,7 +1140,7 @@ protected virtual bool Parse (string argument, OptionContext c)
private void ParseValue (string option, OptionContext c)
{
if (option != null)
foreach (string o in c.Option.ValueSeparators != null
foreach (string o in c.Option.ValueSeparators != null
? option.Split (c.Option.ValueSeparators, c.Option.MaxValueCount - c.OptionValues.Count, StringSplitOptions.None)
: new string[]{option}) {
c.OptionValues.Add (o);
Expand All @@ -1150,7 +1150,7 @@ private void ParseValue (string option, OptionContext c)
c.Option.Invoke (c);
else if (c.OptionValues.Count > c.Option.MaxValueCount) {
throw new OptionException (localizer (string.Format (
"Error: Found {0} option values when expecting {1}.",
"Error: Found {0} option values when expecting {1}.",
c.OptionValues.Count, c.Option.MaxValueCount)),
c.OptionName);
}
Expand Down Expand Up @@ -1301,7 +1301,7 @@ bool WriteOptionPrototype (TextWriter o, Option p, ref int written)
Write (o, ref written, names [0]);
}

for (i = GetNextOptionIndex (names, i + 1);
for (i = GetNextOptionIndex (names, i + 1);
i < names.Length; i = GetNextOptionIndex (names, i + 1)) {
Write (o, ref written, ", ");
Write (o, ref written, names [i].Length == 1 ? "-" : "--");
Expand All @@ -1314,7 +1314,7 @@ bool WriteOptionPrototype (TextWriter o, Option p, ref int written)
Write (o, ref written, localizer ("["));
}
Write (o, ref written, localizer ("=" + GetArgumentName (0, p.MaxValueCount, p.Description)));
string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0
string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0
? p.ValueSeparators [0]
: " ";
for (int c = 1; c < p.MaxValueCount; ++c) {
Expand Down
36 changes: 18 additions & 18 deletions build-tools/jnienv-gen/Mono.Options-PCL.cs
Expand Up @@ -18,10 +18,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -42,16 +42,16 @@
// A Getopt::Long-inspired option parsing library for C#.
//
// NDesk.Options.OptionSet is built upon a key/value table, where the
// key is a option format string and the value is a delegate that is
// key is a option format string and the value is a delegate that is
// invoked when the format string is matched.
//
// Option format strings:
// Regex-like BNF Grammar:
// Regex-like BNF Grammar:
// name: .+
// type: [=:]
// sep: ( [^{}]+ | '{' .+ '}' )?
// aliases: ( name type sep ) ( '|' name type sep )*
//
//
// Each '|'-delimited name is an alias for the associated action. If the
// format string ends in a '=', it has a required value. If the format
// string ends in a ':', it has an optional value. If neither '=' or ':'
Expand Down Expand Up @@ -97,7 +97,7 @@
// p.Parse (new string[]{"-v", "--v", "/v", "-name=A", "/name", "B", "extra"});
//
// The above would parse the argument string array, and would invoke the
// lambda expression three times, setting `verbose' to 3 when complete.
// lambda expression three times, setting `verbose' to 3 when complete.
// It would also print out "A" and "B" to standard output.
// The returned array would contain the string "extra".
//
Expand Down Expand Up @@ -364,7 +364,7 @@ private void AssertValid (int index)
if (c.Option.OptionValueType == OptionValueType.Required &&
index >= values.Count)
throw new OptionException (string.Format (
c.OptionSet.MessageLocalizer ("Missing required value for option '{0}'."), c.OptionName),
c.OptionSet.MessageLocalizer ("Missing required value for option '{0}'."), c.OptionName),
c.OptionName);
}

Expand Down Expand Up @@ -415,7 +415,7 @@ public OptionContext (OptionSet set)
set { option = value; }
}

public string OptionName {
public string OptionName {
get { return name; }
set { name = value; }
}
Expand Down Expand Up @@ -519,7 +519,7 @@ public string[] GetNames ()
public string[] GetValueSeparators ()
{
if (separators == null)
return new string [0];
return Array.Empty<string> ();
return (string[])separators.Clone ();
}

Expand Down Expand Up @@ -672,10 +672,10 @@ static IEnumerable<string> GetArguments (TextReader reader, bool close)

for (int i = 0; i < t; i++) {
char c = line [i];

if (c == '"' || c == '\'') {
char end = c;

for (i++; i < t; i++) {
c = line [i];

Expand Down Expand Up @@ -889,7 +889,7 @@ public OptionSet Add (string prototype, string description, Action<string> actio
{
if (action == null)
throw new ArgumentNullException ("action");
Option p = new ActionOption (prototype, description, 1,
Option p = new ActionOption (prototype, description, 1,
delegate (OptionValueCollection v) {
action (v [0]);
}, hidden);
Expand All @@ -911,7 +911,7 @@ public OptionSet Add (string prototype, string description, OptionAction<string,
{
if (action == null)
throw new ArgumentNullException ("action");
Option p = new ActionOption (prototype, description, 2,
Option p = new ActionOption (prototype, description, 2,
delegate (OptionValueCollection v) {
action (v [0], v [1]);
}, hidden);
Expand Down Expand Up @@ -1121,7 +1121,7 @@ protected virtual bool Parse (string argument, OptionContext c)
c.Option.Invoke (c);
break;
case OptionValueType.Optional:
case OptionValueType.Required:
case OptionValueType.Required:
ParseValue (v, c);
break;
}
Expand All @@ -1140,7 +1140,7 @@ protected virtual bool Parse (string argument, OptionContext c)
private void ParseValue (string option, OptionContext c)
{
if (option != null)
foreach (string o in c.Option.ValueSeparators != null
foreach (string o in c.Option.ValueSeparators != null
? option.Split (c.Option.ValueSeparators, c.Option.MaxValueCount - c.OptionValues.Count, StringSplitOptions.None)
: new string[]{option}) {
c.OptionValues.Add (o);
Expand All @@ -1150,7 +1150,7 @@ private void ParseValue (string option, OptionContext c)
c.Option.Invoke (c);
else if (c.OptionValues.Count > c.Option.MaxValueCount) {
throw new OptionException (localizer (string.Format (
"Error: Found {0} option values when expecting {1}.",
"Error: Found {0} option values when expecting {1}.",
c.OptionValues.Count, c.Option.MaxValueCount)),
c.OptionName);
}
Expand Down Expand Up @@ -1301,7 +1301,7 @@ bool WriteOptionPrototype (TextWriter o, Option p, ref int written)
Write (o, ref written, names [0]);
}

for (i = GetNextOptionIndex (names, i + 1);
for (i = GetNextOptionIndex (names, i + 1);
i < names.Length; i = GetNextOptionIndex (names, i + 1)) {
Write (o, ref written, ", ");
Write (o, ref written, names [i].Length == 1 ? "-" : "--");
Expand All @@ -1314,7 +1314,7 @@ bool WriteOptionPrototype (TextWriter o, Option p, ref int written)
Write (o, ref written, localizer ("["));
}
Write (o, ref written, localizer ("=" + GetArgumentName (0, p.MaxValueCount, p.Description)));
string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0
string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0
? p.ValueSeparators [0]
: " ";
for (int c = 1; c < p.MaxValueCount; ++c) {
Expand Down
Expand Up @@ -52,7 +52,7 @@ public override bool Execute ()

if (LogTaskMessages) {
Log.LogMessage (MessageImportance.Low, $" [Output] {nameof (Output)}:");
foreach (var line in (Output ?? new string [0]))
foreach (var line in (Output ?? Array.Empty<string> ()))
Log.LogMessage (MessageImportance.Low, $" {line}");
}

Expand Down

0 comments on commit 550325a

Please sign in to comment.