Skip to content

Commit

Permalink
[Xamarin.Andorid.Build.Tasks] reduce task time
Browse files Browse the repository at this point in the history
This commit does 3 changes to ConvertResourceCase, in order to
drastically reduces execution times. On my sample, execution times are
less than half of the original times:

- simplify the linq query used to get the `xmls` files (thx
- compute `reosurcedictionaries` out of the loop`
- do not create a temp file as UpdateXmlResource already creates a temp
file. Change the return value of UpdateXmlResource to indicate if the
file has been changed or not.
  • Loading branch information
StephaneDelcroix authored and jonathanpeppers committed Aug 22, 2018
1 parent d8f4335 commit 9527ffc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 60 deletions.
87 changes: 41 additions & 46 deletions src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,25 @@ void FixupResources (ITaskItem item, Dictionary<string, string> acwMap)
{
var resdir = item.ItemSpec;
// Find all the xml and axml files
var xmls = new[] { resdir }
.Concat (Directory.EnumerateDirectories (resdir, "*", SearchOption.AllDirectories)
.Except (Directory.EnumerateDirectories (resdir, "color*", SearchOption.TopDirectoryOnly))
.Except (Directory.EnumerateDirectories (resdir, "raw*", SearchOption.TopDirectoryOnly)))
.SelectMany (dir => Directory.EnumerateFiles (dir, "*.xml")
.Concat (Directory.EnumerateFiles (dir, "*.axml")));
var xmls = new List<string> ();
var colorDir = Path.Combine (resdir, "color");
var rawDir = Path.Combine (resdir, "raw");
foreach (var file in Directory.GetFiles (resdir, "*.*xml", SearchOption.AllDirectories)) {
if (file.StartsWith (colorDir, StringComparison.Ordinal) || file.StartsWith (rawDir, StringComparison.Ordinal))
continue;
var ext = Path.GetExtension (file);
if (ext != ".xml" && ext != ".axml")
continue;
xmls.Add (file);
}

var lastUpdate = DateTime.MinValue;
if (!string.IsNullOrEmpty (AndroidConversionFlagFile) && File.Exists (AndroidConversionFlagFile)) {
lastUpdate = File.GetLastWriteTimeUtc (AndroidConversionFlagFile);
}
Log.LogDebugMessage (" AndroidConversionFlagFile modified: {0}", lastUpdate);

var resourcedirectories = ResourceDirectories.Where (s => s != item).Select(s => s.ItemSpec).ToArray();
// Fix up each file
foreach (string file in xmls) {
var srcmodifiedDate = File.GetLastWriteTimeUtc (file);
Expand All @@ -73,47 +80,35 @@ void FixupResources (ITaskItem item, Dictionary<string, string> acwMap)
continue;
}
Log.LogDebugMessage (" Processing: {0} {1} > {2}", file, srcmodifiedDate, lastUpdate);
var tmpdest = Path.GetTempFileName ();
File.Copy (file, tmpdest, overwrite: true);
MonoAndroidHelper.SetWriteable (tmpdest);
try {
bool success = AndroidResource.UpdateXmlResource (resdir, tmpdest, acwMap,
ResourceDirectories.Where (s => s != item).Select(s => s.ItemSpec), (t, m) => {
string targetfile = file;
if (targetfile.StartsWith (resdir, StringComparison.InvariantCultureIgnoreCase)) {
targetfile = file.Substring (resdir.Length).TrimStart (Path.DirectorySeparatorChar);
if (resource_name_case_map.TryGetValue (targetfile, out string temp))
targetfile = temp;
targetfile = Path.Combine ("Resources", targetfile);
}
switch (t) {
case TraceLevel.Error:
Log.LogCodedError ("XA1002", file: targetfile, lineNumber: 0, message: m);
break;
case TraceLevel.Warning:
Log.LogCodedWarning ("XA1001", file: targetfile, lineNumber: 0, message: m);
break;
default:
Log.LogDebugMessage (m);
break;
}
});
if (!success) {
//If we failed to write the file, a warning is logged, we should skip to the next file
continue;
}

// We strip away an eventual UTF-8 BOM from the XML file.
// This is a requirement for the Android designer because the desktop Java renderer
// doesn't support those type of BOM (it really wants the document to start
// with "<?"). Since there is no way to plug into the file saving mechanism in X.S
// we strip those here and point the designer to use resources from obj/
MonoAndroidHelper.CleanBOM (tmpdest);
if (!AndroidResource.UpdateXmlResource(resdir, file, acwMap, resourcedirectories,
(t, m) => {
string targetfile = file;
if (targetfile.StartsWith(resdir, StringComparison.InvariantCultureIgnoreCase)) {
targetfile = file.Substring(resdir.Length).TrimStart(Path.DirectorySeparatorChar);
if (resource_name_case_map.TryGetValue(targetfile, out string temp))
targetfile = temp;
targetfile = Path.Combine("Resources", targetfile);
}
switch (t) {
case TraceLevel.Error:
Log.LogCodedError("XA1002", file: targetfile, lineNumber: 0, message: m);
break;
case TraceLevel.Warning:
Log.LogCodedWarning("XA1001", file: targetfile, lineNumber: 0, message: m);
break;
default:
Log.LogDebugMessage(m);
break;
}
}))
continue;

MonoAndroidHelper.CopyIfChanged (tmpdest, file);
} finally {
File.Delete (tmpdest);
}
// We strip away an eventual UTF-8 BOM from the XML file.
// This is a requirement for the Android designer because the desktop Java renderer
// doesn't support those type of BOM (it really wants the document to start
// with "<?"). Since there is no way to plug into the file saving mechanism in X.S
// we strip those here and point the designer to use resources from obj/
MonoAndroidHelper.CleanBOM (file);
}
}
}
Expand Down
15 changes: 3 additions & 12 deletions src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,10 @@ public override bool Execute ()
var destfilename = p.Value;
var srcmodifiedDate = File.GetLastWriteTimeUtc (filename);
var dstmodifiedDate = File.Exists (destfilename) ? File.GetLastWriteTimeUtc (destfilename) : DateTime.MinValue;
var tmpdest = Path.GetTempFileName ();
var res = Path.Combine (Path.GetDirectoryName (filename), "..");
MonoAndroidHelper.CopyIfChanged (filename, tmpdest);
MonoAndroidHelper.SetWriteable (tmpdest);
try {
AndroidResource.UpdateXmlResource (res, tmpdest, acw_map);
if (MonoAndroidHelper.CopyIfChanged (tmpdest, destfilename)) {
if (!modifiedFiles.Any (i => i.ItemSpec == destfilename))
modifiedFiles.Add (new TaskItem (destfilename));
}
} finally {
File.Delete (tmpdest);
}

if (AndroidResource.UpdateXmlResource (res, filename, acw_map) && !modifiedFiles.Any (i => i.ItemSpec == destfilename))
modifiedFiles.Add (new TaskItem(destfilename));
}
merger.Save ();
ModifiedFiles = modifiedFiles.ToArray ();
Expand Down
4 changes: 2 additions & 2 deletions src/Xamarin.Android.Build.Tasks/Utilities/AndroidResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public static bool UpdateXmlResource (string res, string filename, Dictionary<st
using (var stream = File.OpenWrite (tmpfile))
using (var xw = new LinePreservedXmlWriter (new StreamWriter (stream)))
xw.WriteNode (doc.CreateNavigator (), false);
Xamarin.Android.Tasks.MonoAndroidHelper.CopyIfChanged (tmpfile, filename);
var changed = Xamarin.Android.Tasks.MonoAndroidHelper.CopyIfChanged (tmpfile, filename);
File.Delete (tmpfile);
return true;
return changed;
} catch (Exception e) {
if (File.Exists (tmpfile)) {
File.Delete (tmpfile);
Expand Down

0 comments on commit 9527ffc

Please sign in to comment.