From 985dacd494cbfc8278990da228e76bd5925076a1 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Fri, 25 Oct 2019 01:03:55 -0400 Subject: [PATCH] Performance optimizations - replace foreach with for --- .../UniversalEditor.Core/Association.cs | 66 ++++--------------- .../Common/Reflection.cs | 42 +++++++----- .../DataFormats/Markup/XML/XMLDataFormat.cs | 59 ++++++++--------- 3 files changed, 64 insertions(+), 103 deletions(-) diff --git a/CSharp/Libraries/UniversalEditor.Core/Association.cs b/CSharp/Libraries/UniversalEditor.Core/Association.cs index 0cd5ec9f..f13d267c 100644 --- a/CSharp/Libraries/UniversalEditor.Core/Association.cs +++ b/CSharp/Libraries/UniversalEditor.Core/Association.cs @@ -62,72 +62,28 @@ namespace UniversalEditor { Association[] _associations = Association.GetAllAssociations(); List associations = new List(); - foreach (Association assoc in _associations) + for (int i = 0; i < _associations.Length; i++) { - if ((objectModel != null && assoc.ObjectModels.Contains(objectModel)) || (dataFormat != null && assoc.DataFormats.Contains(dataFormat))) + if ((objectModel != null && _associations[i].ObjectModels.Contains(objectModel)) || (dataFormat != null && _associations[i].DataFormats.Contains(dataFormat))) { - associations.Add(assoc); + associations.Add(_associations[i]); } } return associations.ToArray(); } public static Association[] FromAccessor(Accessor accessor = null, string fileNameFilter = null) { - Association[] _associations = Association.GetAllAssociations(); + Association[] assocs = Association.GetAllAssociations(); List associations = new List(); - Association[] assocs = _associations; - foreach (Association assoc in assocs) - { - foreach (DataFormatFilter filter in assoc.Filters) - { - if (accessor != null) - { - for (int i = 0; i < filter.MagicBytes.Count; i++) - { - byte?[] bytes = filter.MagicBytes[i]; - if ((accessor.Position + bytes.Length) <= accessor.Length) - { - bool ret = true; - byte[] cmp = new byte[bytes.Length]; - long offset = accessor.Position; - if (i < filter.MagicByteOffsets.Length) - { - if (filter.MagicByteOffsets[i] < 0) - { - accessor.Seek(filter.MagicByteOffsets[i], SeekOrigin.End); - } - else - { - accessor.Seek(filter.MagicByteOffsets[i], SeekOrigin.Begin); - } - } - accessor.Reader.Read(cmp, 0, cmp.Length); - accessor.Position = offset; - for (int j = 0; j < bytes.Length; j++) - { - if (bytes[j] == null) continue; - if (bytes[j] != cmp[j]) - { - ret = false; - break; - } - } - if (ret) - { - associations.Add(assoc); - break; - } - } - } - } - if (fileNameFilter != null) + // stopwatch diagnostics determined a nested for loop is 0.0547024 ms faster than foreach + for (int i = 0; i < assocs.Length; i++) + { + for (int j = 0; j < assocs[i].Filters.Count; j++) + { + if (assocs[i].Filters[j].Matches(accessor)) { - if (filter.FileNameFilters.Contains(fileNameFilter)) - { - associations.Add(assoc); - break; - } + associations.Add(assocs[i]); } } } diff --git a/CSharp/Libraries/UniversalEditor.Essential/Common/Reflection.cs b/CSharp/Libraries/UniversalEditor.Essential/Common/Reflection.cs index c587c0b2..f219c45c 100644 --- a/CSharp/Libraries/UniversalEditor.Essential/Common/Reflection.cs +++ b/CSharp/Libraries/UniversalEditor.Essential/Common/Reflection.cs @@ -37,8 +37,9 @@ namespace UniversalEditor.Common { List types = new List(); Assembly[] asms = GetAvailableAssemblies(); - foreach (Assembly asm in asms) + for (int iAsm = 0; iAsm < asms.Length; iAsm++) { + Assembly asm = asms[iAsm]; Type[] types1 = null; try { @@ -54,10 +55,10 @@ namespace UniversalEditor.Common if (types1 == null) continue; - foreach (Type type in types1) + for (int jTyp = 0; jTyp < types1.Length; jTyp++) { - if (type == null) continue; - types.Add(type); + if (types1[jTyp] == null) continue; + types.Add(types1[jTyp]); } } mvarAvailableTypes = types.ToArray(); @@ -66,11 +67,11 @@ namespace UniversalEditor.Common if (inheritsFrom != null) { List retval = new List(); - foreach (Type tAvailable in mvarAvailableTypes) + for (int iTyp = 0; iTyp < mvarAvailableTypes.Length; iTyp++) { - foreach (Type tInheritsFrom in inheritsFrom) + for (int jInh = 0; jInh < inheritsFrom.Length; jInh++) { - if (tAvailable.IsSubclassOf(tInheritsFrom)) retval.Add(tAvailable); + if (mvarAvailableTypes[iTyp].IsSubclassOf(inheritsFrom[jInh])) retval.Add(mvarAvailableTypes[iTyp]); } } return retval.ToArray(); @@ -95,8 +96,9 @@ namespace UniversalEditor.Common List listConverters = new List(); List listProjectTypes = new List(); { - foreach (Type type in types) + for (int iTyp = 0; iTyp < types.Length; iTyp++) { + Type type = types[iTyp]; if (type == null) continue; if (mvarAvailableObjectModels == null && (type.IsSubclassOf(typeof(ObjectModel)) && !type.IsAbstract)) { @@ -232,8 +234,9 @@ namespace UniversalEditor.Common private static void InitializeFromXML(ref List listObjectModels, ref List listDataFormats, ref List listProjectTypes, ref List listDocumentTemplates, ref List listProjectTemplates) { string[] paths = EnumerateDataPaths(); - foreach (string path in paths) + for (int iPath = 0; iPath < paths.Length; iPath++) { + string path = paths[iPath]; if (!System.IO.Directory.Exists(path)) { Console.WriteLine("skipping nonexistent directory {0}", path); @@ -245,8 +248,9 @@ namespace UniversalEditor.Common string[] XMLFileNames = null; XMLFileNames = System.IO.Directory.GetFiles(path, configurationFileNameFilter, System.IO.SearchOption.AllDirectories); - foreach (string fileName in XMLFileNames) + for (int jFileName = 0; jFileName < XMLFileNames.Length; jFileName++) { + string fileName = XMLFileNames[jFileName]; #if !DEBUG try { @@ -282,8 +286,9 @@ namespace UniversalEditor.Common // ensure project types are loaded before running the next pass mvarAvailableProjectTypes = listProjectTypes.ToArray(); - foreach (string fileName in XMLFileNames) + for (int jFileName = 0; jFileName < XMLFileNames.Length; jFileName++) { + string fileName = XMLFileNames[jFileName]; try { UEPackageObjectModel mom = new UEPackageObjectModel(); @@ -293,18 +298,18 @@ namespace UniversalEditor.Common Document.Load(om, xdf, new FileAccessor(fileName, false, false, false), true); - foreach (DocumentTemplate template in mom.DocumentTemplates) + for (int kTemp = 0; kTemp < mom.DocumentTemplates.Count; kTemp++) { - listDocumentTemplates.Add(template); + listDocumentTemplates.Add(mom.DocumentTemplates[kTemp]); } - foreach (ProjectTemplate template in mom.ProjectTemplates) + for (int kTemp = 0; kTemp < mom.ProjectTemplates.Count; kTemp++) { - listProjectTemplates.Add(template); + listProjectTemplates.Add(mom.ProjectTemplates[kTemp]); } - foreach (Association assoc in mom.Associations) + for (int kAssoc = 0; kAssoc < mom.Associations.Count; kAssoc++) { - Association.Register(assoc); + Association.Register(mom.Associations[kAssoc]); } } catch @@ -341,8 +346,9 @@ namespace UniversalEditor.Common DataFormatReference[] dfrs = GetAvailableDataFormats(omr); - foreach (DataFormatReference dfr in dfrs) + for (int i = 0; i < dfrs.Length; i++) { + DataFormatReference dfr = dfrs[i]; try { DataFormat df = dfr.Create(); diff --git a/CSharp/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs b/CSharp/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs index 394b5d55..12519988 100644 --- a/CSharp/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs +++ b/CSharp/Libraries/UniversalEditor.Essential/DataFormats/Markup/XML/XMLDataFormat.cs @@ -70,7 +70,7 @@ namespace UniversalEditor.DataFormats.Markup.XML if (element.Value.Contains(Environment.NewLine)) { tw.Write(Settings.TagBeginChar.ToString() + Settings.PreprocessorChar.ToString() + element.Name + " "); - + if (mvarSettings.PrettyPrint) tw.WriteLine(); tw.Write(element.Value); if (mvarSettings.PrettyPrint) tw.WriteLine(); @@ -96,19 +96,18 @@ namespace UniversalEditor.DataFormats.Markup.XML { tw.Write(" "); } - foreach (MarkupAttribute att in tag.Attributes) + for (int i = 0; i < tag.Attributes.Count; i++) { - tw.Write(att.FullName + "=\"" + this.ReplaceEntitiesOutput(att.Value) + "\""); - if (tag.Attributes.IndexOf(att) < tag.Attributes.Count - 1) - { - tw.Write(" "); - } + MarkupAttribute att = tag.Attributes[i]; + tw.Write(String.Format("{0}=\"{1}\"", att.FullName, this.ReplaceEntitiesOutput(att.Value))); + + if (i < tag.Attributes.Count - 1) tw.Write(" "); } if (tag.Elements.Count == 0) { if (String.IsNullOrEmpty(element.Value)) { - tw.Write(" " + Settings.TagCloseChar.ToString() + Settings.TagEndChar.ToString()); + tw.Write(String.Format(" {0}{1}", Settings.TagCloseChar.ToString(), Settings.TagEndChar.ToString())); if (mvarSettings.PrettyPrint) tw.WriteLine(); } else @@ -133,7 +132,7 @@ namespace UniversalEditor.DataFormats.Markup.XML tw.Write(Settings.TagSpecialDeclarationCommentStart); bool containsNewline = element.Value.ContainsAny(new string[] { - "\r", + "\r", "\n" }); if (containsNewline) @@ -809,7 +808,7 @@ namespace UniversalEditor.DataFormats.Markup.XML string specialSectionContent = tr.ReadUntil(this.Settings.CDataEndChar.ToString()); if (specialSectionContent.Length > 0) { - specialSectionContent = specialSectionContent.Substring(0, specialSectionContent.Length); + specialSectionContent = specialSectionContent.Substring(0, specialSectionContent.Length); } MarkupStringElement tag = new MarkupStringElement(); @@ -940,14 +939,14 @@ namespace UniversalEditor.DataFormats.Markup.XML WriteStartTag(mvarCompensateTopLevelTagName); } - if (!(mom.Elements.Count > 0 && mom.Elements [0] is MarkupPreprocessorElement && (mom.Elements [0] as MarkupPreprocessorElement).FullName == "xml")) + if (!(mom.Elements.Count > 0 && mom.Elements[0] is MarkupPreprocessorElement && (mom.Elements[0] as MarkupPreprocessorElement).FullName == "xml")) { - tw.WriteLine (""); + tw.WriteLine(""); } - foreach (MarkupElement element in mom.Elements) + for (int i = 0; i < mom.Elements.Count; i++) { - WriteElement(element, 0); + WriteElement(mom.Elements[i], 0); } if (mom.Elements.Count > 1 && (mvarCompensateTopLevelTagName != null)) @@ -972,13 +971,13 @@ namespace UniversalEditor.DataFormats.Markup.XML tw.Write(this.Settings.TagEndChar.ToString()); if (mvarSettings.PrettyPrint) tw.WriteLine(); - foreach (Group g in plom.Groups) + for (int i = 0; i < plom.Groups.Count; i++) { - this.WriteXMLPropertyGroup(tw, g, 1); + this.WriteXMLPropertyGroup(tw, plom.Groups[i], 1); } - foreach (Property p in plom.Properties) + for (int i = 0; i < plom.Properties.Count; i++) { - this.WriteXMLProperty(tw, p, 1); + this.WriteXMLProperty(tw, plom.Properties[i], 1); } tw.Write(this.Settings.TagBeginChar.ToString()); @@ -1000,13 +999,13 @@ namespace UniversalEditor.DataFormats.Markup.XML tw.Write(arg_37_0 + arg_37_1 + c.ToString()); if (mvarSettings.PrettyPrint) tw.WriteLine(); - foreach (Group g2 in g.Groups) + for (int i = 0; i < g.Groups.Count; i++) { - this.WriteXMLPropertyGroup(tw, g2, indentLevel + 1); + this.WriteXMLPropertyGroup(tw, g.Groups[i], indentLevel + 1); } - foreach (Property p in g.Properties) + for (int i = 0; i < g.Properties.Count; i++) { - this.WriteXMLProperty(tw, p, indentLevel + 1); + this.WriteXMLProperty(tw, g.Properties[i], indentLevel + 1); } c = this.Settings.TagBeginChar; string arg_116_0 = c.ToString(); @@ -1590,19 +1589,19 @@ namespace UniversalEditor.DataFormats.Markup.XML { switch (attType.Value) { - /* - case "xsd:string": - { - return tag.Value; - } - */ - case "xsd:integer": + /* + case "xsd:string": + { + return tag.Value; + } + */ + case "xsd:integer": { return Int32.Parse(tag.Value); } } } - + MarkupAttribute attNil = tag.Attributes["xsi:nil"]; // return null if xsi:nil attribute is present if (attNil != null) return null;