Several fixes to the compiler performance code

This commit is contained in:
halgari 2022-09-24 16:13:29 -05:00
parent e71abd82f7
commit 6958f34c32
5 changed files with 74 additions and 4 deletions

View File

@ -62,6 +62,47 @@ public static class AsyncParallelExtensions
} }
} }
/// <summary>
/// Faster version of PMapAll for when the function invocation will take a very small amount of time
/// batches all the inputs into N groups and executes them all on one task, where N is the number of
/// threads supported by the limiter
/// </summary>
/// <param name="coll"></param>
/// <param name="limiter"></param>
/// <param name="mapFn"></param>
/// <typeparam name="TIn"></typeparam>
/// <typeparam name="TJob"></typeparam>
/// <typeparam name="TOut"></typeparam>
/// <returns></returns>
public static async IAsyncEnumerable<TOut> PMapAllBatched<TIn, TJob, TOut>(this IEnumerable<TIn> coll,
IResource<TJob> limiter, Func<TIn, Task<TOut>> mapFn)
{
var asList = coll.ToList();
var tasks = new List<Task<List<TOut>>>();
tasks.AddRange(Enumerable.Range(0, limiter.MaxTasks).Select(i => Task.Run(async () =>
{
using var job = await limiter.Begin(limiter.Name, asList.Count / limiter.MaxTasks, CancellationToken.None);
var list = new List<TOut>();
for (var idx = i; idx < asList.Count; idx += limiter.MaxTasks)
{
job.ReportNoWait(1);
list.Add(await mapFn(asList[idx]));
}
return list;
})));
foreach (var result in tasks)
{
foreach (var itm in (await result))
{
yield return itm;
}
}
}
public static async IAsyncEnumerable<TOut> PKeepAll<TIn, TJob, TOut>(this IEnumerable<TIn> coll, public static async IAsyncEnumerable<TOut> PKeepAll<TIn, TJob, TOut>(this IEnumerable<TIn> coll,
IResource<TJob> limiter, Func<TIn, Task<TOut>> mapFn) IResource<TJob> limiter, Func<TIn, Task<TOut>> mapFn)
where TOut : class where TOut : class

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Wabbajack.Common; namespace Wabbajack.Common;
@ -11,8 +12,9 @@ public static class IEnumerableExtensions
{ {
foreach (var i in coll) f(i); foreach (var i in coll) f(i);
} }
#region Shuffle #region Shuffle
/// https://stackoverflow.com/questions/5807128/an-extension-method-on-ienumerable-needed-for-shuffling /// https://stackoverflow.com/questions/5807128/an-extension-method-on-ienumerable-needed-for-shuffling
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng) public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
@ -32,6 +34,7 @@ public static class IEnumerableExtensions
buffer[j] = buffer[i]; buffer[j] = buffer[i];
} }
} }
#endregion #endregion
@ -55,6 +58,22 @@ public static class IEnumerableExtensions
return data; return data;
} }
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> coll, int size)
{
var asList = coll.ToList();
IEnumerable<T> SkipEnumerable(IList<T> list, int offset, int size)
{
for (var i = offset; i < list.Count; i += size)
{
yield return list[i];
}
}
return Enumerable.Range(0, size).Select(offset => SkipEnumerable(asList, offset, size));
}
public static IEnumerable<T> OnEach<T>(this IEnumerable<T> coll, Action<T> fn) public static IEnumerable<T> OnEach<T>(this IEnumerable<T> coll, Action<T> fn)
{ {
foreach (var itm in coll) foreach (var itm in coll)

View File

@ -141,7 +141,7 @@ public class MO2Compiler : ACompiler
var stack = MakeStack(); var stack = MakeStack();
NextStep("Compiling", "Running Compilation Stack", AllFiles.Count); NextStep("Compiling", "Running Compilation Stack", AllFiles.Count);
var results = await AllFiles.PMapAll(CompilerLimiter, f => var results = await AllFiles.PMapAllBatched(CompilerLimiter, f =>
{ {
UpdateProgress(1); UpdateProgress(1);
return RunStack(stack, f); return RunStack(stack, f);

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
namespace Wabbajack.Paths.IO; namespace Wabbajack.Paths.IO;
@ -13,8 +14,15 @@ public static class KnownFolders
{ {
var result = Process.GetCurrentProcess().MainModule?.FileName?.ToAbsolutePath() ?? default; var result = Process.GetCurrentProcess().MainModule?.FileName?.ToAbsolutePath() ?? default;
if (result != default &&
result.PathParts.Any(p => p.Equals("TestRunner", StringComparison.CurrentCultureIgnoreCase)))
{
return Assembly.GetExecutingAssembly().Location.ToAbsolutePath().Parent;
}
if ((result != default && result.Depth > 1 && result.FileName == "dotnet".ToRelativePath()) || Assembly.GetEntryAssembly() != null)
if ((result != default && result.Depth > 1 && result.FileName == "dotnet".ToRelativePath())
|| Assembly.GetEntryAssembly() != null)
{ {
result = Assembly.GetEntryAssembly()!.Location.ToAbsolutePath(); result = Assembly.GetEntryAssembly()!.Location.ToAbsolutePath();
} }

View File

@ -18,9 +18,11 @@ public struct AbsolutePath : IPath, IComparable<AbsolutePath>, IEquatable<Absolu
public PathFormat PathFormat { get; } public PathFormat PathFormat { get; }
private int _hashCode = 0; private int _hashCode = 0;
internal readonly string[] Parts; internal readonly string[] Parts;
public string[] PathParts => Parts == default ? Array.Empty<string>() : Parts;
public Extension Extension => Extension.FromPath(Parts[^1]); public Extension Extension => Extension.FromPath(Parts[^1]);
public RelativePath FileName => new(Parts[^1..]); public RelativePath FileName => new(Parts[^1..]);