From e77214b2de03bc6feb9355d7e2bfd22db35e180b Mon Sep 17 00:00:00 2001 From: Dev Date: Mon, 18 Sep 2023 17:15:30 +0100 Subject: [PATCH] Further optimisation from Clodan --- Common.Models/Input/Settings.cs | 1 + Common/Bot/BotParser.cs | 6 +-- Generator/BotChancesGenerator.cs | 52 ++++++++++-------- Generator/BotGearGenerator.cs | 50 ++++++++++------- Generator/BotLootGenerator.cs | 60 ++++++++++++--------- Generator/Helpers/Gear/GearChanceHelpers.cs | 2 +- Generator/Program.cs | 19 +++++-- 7 files changed, 115 insertions(+), 75 deletions(-) diff --git a/Common.Models/Input/Settings.cs b/Common.Models/Input/Settings.cs index ab98a63..5f11343 100644 --- a/Common.Models/Input/Settings.cs +++ b/Common.Models/Input/Settings.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Runtime.Serialization; diff --git a/Common/Bot/BotParser.cs b/Common/Bot/BotParser.cs index e67617c..2206338 100644 --- a/Common/Bot/BotParser.cs +++ b/Common/Bot/BotParser.cs @@ -25,9 +25,9 @@ public static class BotParser var parsedBotsDict = new HashSet(); var dictionaryLock = new object(); - + int totalDupeCount = 0; - + var tasks = new List(50); foreach (var file in botFiles) { @@ -102,7 +102,7 @@ public static class BotParser Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); - + LoggingHelpers.LogToConsole($"Cleaned and Parsed: {parsedBotsDict.Count} bots. {totalDupeCount} dupes were ignored. Took {LoggingHelpers.LogTimeTaken(stopwatch.Elapsed.TotalSeconds)} seconds"); return parsedBotsDict.ToList(); diff --git a/Generator/BotChancesGenerator.cs b/Generator/BotChancesGenerator.cs index 0d9fc5b..6e86c74 100644 --- a/Generator/BotChancesGenerator.cs +++ b/Generator/BotChancesGenerator.cs @@ -1,47 +1,57 @@ -using Common; -using Generator.Helpers.Gear; +using Generator.Helpers.Gear; using Common.Models.Input; using Common.Models.Output; -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using Generator.Weighting; namespace Generator { public static class BotChancesGenerator { - public static IEnumerable AddChances(this IEnumerable botsToUpdate, IEnumerable rawBots) + public static IEnumerable AddChances(this IEnumerable botsToUpdate, Dictionary> rawBots) { var stopwatch = Stopwatch.StartNew(); LoggingHelpers.LogToConsole("Started processing bot gear"); + // use lock for lock safety + var dictionaryLock = new object(); var weightHelper = new WeightingService(); + // multithread + var tasks = new List(); foreach (var botToUpdate in botsToUpdate) { - var botType = botToUpdate.botType.ToString(); - var rawParsedBotOfCurrentType = rawBots - .Where(x => x.Info.Settings.Role.Equals(botType, StringComparison.OrdinalIgnoreCase)) - .ToList(); - - if (rawParsedBotOfCurrentType.Count == 0) + tasks.Add(Task.Factory.StartNew(() => { - continue; - } + var botType = botToUpdate.botType.ToString().ToLower(); + List rawBotsOfSameType; + lock (dictionaryLock) + { + if (!rawBots.TryGetValue(botType, out rawBotsOfSameType)) + { + Console.WriteLine($"Unable to find {botType} on rawBots data"); + return; + } + } - // TODO: Add check to make sure incoming bot list has gear - GearChanceHelpers.CalculateEquipmentChances(botToUpdate, rawParsedBotOfCurrentType); - GearChanceHelpers.AddGenerationChances(botToUpdate, rawBots, weightHelper); - GearChanceHelpers.CalculateModChances(botToUpdate, rawParsedBotOfCurrentType); - GearChanceHelpers.ApplyModChanceOverrides(botToUpdate); - GearChanceHelpers.ApplyEquipmentChanceOverrides(botToUpdate); + if (rawBotsOfSameType.Count == 0) + { + return; + } + + // TODO: Add check to make sure incoming bot list has gear + GearChanceHelpers.CalculateEquipmentChances(botToUpdate, rawBotsOfSameType); + GearChanceHelpers.AddGenerationChances(botToUpdate, weightHelper); + GearChanceHelpers.CalculateModChances(botToUpdate, rawBotsOfSameType); + GearChanceHelpers.ApplyModChanceOverrides(botToUpdate); + GearChanceHelpers.ApplyEquipmentChanceOverrides(botToUpdate); + })); } + Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); LoggingHelpers.LogToConsole($"Finished processing bot chances. Took {LoggingHelpers.LogTimeTaken(stopwatch.Elapsed.TotalSeconds)} seconds"); return botsToUpdate; } } -} \ No newline at end of file +} diff --git a/Generator/BotGearGenerator.cs b/Generator/BotGearGenerator.cs index c11e8e7..3a9505f 100644 --- a/Generator/BotGearGenerator.cs +++ b/Generator/BotGearGenerator.cs @@ -1,41 +1,51 @@ -using Common; -using Common.Models.Input; +using Common.Models.Input; using Common.Models.Output; using Generator.Helpers.Gear; -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; namespace Generator { public static class BotGearGenerator { - public static IEnumerable AddGear(this IEnumerable baseBots, IEnumerable rawBots) + public static IEnumerable AddGear(this IEnumerable baseBots, Dictionary> rawBots) { var stopwatch = Stopwatch.StartNew(); LoggingHelpers.LogToConsole("Started processing bot gear"); + var dictionaryLock = new object(); + var tasks = new List(); + foreach (var botToUpdate in baseBots) { - var botType = botToUpdate.botType.ToString(); - var rawParsedBotOfCurrentType = rawBots.Where(x => x.Info.Settings.Role.Equals(botType, StringComparison.OrdinalIgnoreCase)) - .ToList(); - - if (rawParsedBotOfCurrentType.Count == 0) + tasks.Add(Task.Factory.StartNew(() => { - continue; - } + var botType = botToUpdate.botType.ToString().ToLower(); + List rawBotsOfSameType; + lock (dictionaryLock) + { + if (!rawBots.TryGetValue(botType, out rawBotsOfSameType)) + { + Console.WriteLine($"Unable to find {botType} on rawBots data"); + return; + } + } - foreach (var rawParsedBot in rawParsedBotOfCurrentType) - { - GearHelpers.AddEquippedGear(botToUpdate, rawParsedBot); - GearHelpers.AddAmmo(botToUpdate, rawParsedBot); - GearHelpers.AddEquippedMods(botToUpdate, rawParsedBot); - //GearHelpers.AddCartridges(botToUpdate, rawParsedBot); - } + if (rawBotsOfSameType.Count == 0) + { + return; + } + + foreach (var rawParsedBot in rawBotsOfSameType) + { + GearHelpers.AddEquippedGear(botToUpdate, rawParsedBot); + GearHelpers.AddAmmo(botToUpdate, rawParsedBot); + GearHelpers.AddEquippedMods(botToUpdate, rawParsedBot); + //GearHelpers.AddCartridges(botToUpdate, rawParsedBot); + } + })); } + Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); LoggingHelpers.LogToConsole($"Finished processing bot gear. Took {LoggingHelpers.LogTimeTaken(stopwatch.Elapsed.TotalSeconds)} seconds"); diff --git a/Generator/BotLootGenerator.cs b/Generator/BotLootGenerator.cs index 3b12f8f..44fc9ab 100644 --- a/Generator/BotLootGenerator.cs +++ b/Generator/BotLootGenerator.cs @@ -1,46 +1,54 @@ -using Common; +using System.Diagnostics; using Common.Extensions; using Common.Models.Input; using Common.Models.Output; using Generator.Helpers.Gear; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; namespace Generator { public static class BotLootGenerator { - internal static IEnumerable AddLoot(this IEnumerable botsWithGear, IEnumerable rawBots) + internal static IEnumerable AddLoot(this IEnumerable botsWithGear, Dictionary> rawBots) { var stopwatch = Stopwatch.StartNew(); LoggingHelpers.LogToConsole("Started processing bot loot"); - // Iterate over assault/raider etc - Parallel.ForEach(botsWithGear, botToUpdate => + var dictionaryLock = new object(); + + var tasks = new List(50); + foreach (var botToUpdate in botsWithGear) { - var botType = botToUpdate.botType.ToString(); - var rawBotsOfSameType = rawBots - .Where(x => x.Info.Settings.Role.Equals(botType, StringComparison.OrdinalIgnoreCase)) - .ToList(); - - if (rawBotsOfSameType.Count == 0) + tasks.Add(Task.Factory.StartNew(() => { - return; - } + var botType = botToUpdate.botType.ToString().ToLower(); + List rawBotsOfSameType; + lock (dictionaryLock) + { + if (!rawBots.TryGetValue(botType, out rawBotsOfSameType)) + { + Console.WriteLine($"Unable to find {botType} on rawBots data"); + return; + } + } - foreach (var rawParsedBot in rawBotsOfSameType) - { - AddPocketLoot(botToUpdate, rawParsedBot); - } + if (rawBotsOfSameType.Count == 0) + { + return; + } - AddTacticalVestLoot(botToUpdate, rawBotsOfSameType); - AddBackpackLoot(botToUpdate, rawBotsOfSameType); - AddSecureContainerLoot(botToUpdate, rawBotsOfSameType); - AddSpecialLoot(botToUpdate); - }); + foreach (var rawParsedBot in rawBotsOfSameType) + { + AddPocketLoot(botToUpdate, rawParsedBot); + } + + AddTacticalVestLoot(botToUpdate, rawBotsOfSameType); + AddBackpackLoot(botToUpdate, rawBotsOfSameType); + AddSecureContainerLoot(botToUpdate, rawBotsOfSameType); + AddSpecialLoot(botToUpdate); + })); + } + + Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); LoggingHelpers.LogToConsole($"Finished processing bot loot. Took: {LoggingHelpers.LogTimeTaken(stopwatch.Elapsed.TotalSeconds)} seconds"); diff --git a/Generator/Helpers/Gear/GearChanceHelpers.cs b/Generator/Helpers/Gear/GearChanceHelpers.cs index ca9a86c..fcdc334 100644 --- a/Generator/Helpers/Gear/GearChanceHelpers.cs +++ b/Generator/Helpers/Gear/GearChanceHelpers.cs @@ -150,7 +150,7 @@ namespace Generator.Helpers.Gear } } - public static void AddGenerationChances(Bot bot, IEnumerable rawBots, WeightingService weightingService) + public static void AddGenerationChances(Bot bot, WeightingService weightingService) { var weightsData = weightingService.GetBotGenerationWeights(bot.botType); bot.generation = new GenerationChances( diff --git a/Generator/Program.cs b/Generator/Program.cs index 6818514..f753df3 100644 --- a/Generator/Program.cs +++ b/Generator/Program.cs @@ -1,4 +1,5 @@ -using Generator.Helpers; +using Common.Models.Input; +using Generator.Helpers; namespace Generator; @@ -52,6 +53,16 @@ internal static class Program var dumpPath = $"{workingPath}//dumps"; var parsedBots = BotParser.ParseAsync(dumpPath, botTypes.ToHashSet()); + // put in dictionary for better use later on + var rawBotsCache = new Dictionary>(40); + foreach (var rawBot in parsedBots) + { + if (rawBotsCache.TryGetValue(rawBot.Info.Settings.Role.ToLower(), out var botList)) + botList.Add(rawBot); + else + rawBotsCache.Add(rawBot.Info.Settings.Role.ToLower(), new List {rawBot}); + } + if (parsedBots.Count == 0) { LoggingHelpers.LogToConsole("no bots found, unable to continue"); @@ -61,9 +72,9 @@ internal static class Program // Generate the base bot class with basic details (health/body part hp etc) and then append everything else var bots = BaseBotGenerator.GenerateBaseDetails(parsedBots, workingPath, botTypes) - .AddGear(parsedBots) // Add weapons/armor - .AddLoot(parsedBots) - .AddChances(parsedBots); // Add mod/equipment chances + .AddGear(rawBotsCache) // Add weapons/armor + .AddLoot(rawBotsCache) + .AddChances(rawBotsCache); // Add mod/equipment chances // Output bot to json file var jsonWriter = new JsonWriter(workingPath, "output");