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.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading

0 comments on commit 550325a

Please sign in to comment.