From 562e412c74d73e5338972232a4a1bedf218d20b3 Mon Sep 17 00:00:00 2001 From: WilliamQiufeng Date: Sat, 17 Aug 2024 14:40:18 +0800 Subject: [PATCH 1/4] Optimise bin selection in difficulty calculation --- .../Rulesets/Keys/DifficultyProcessorKeys.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs index 467eb6739..56e6c1418 100644 --- a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs +++ b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs @@ -556,12 +556,22 @@ private float CalculateOverallDifficulty() var mapStart = StrainSolverData.Min(s => s.StartTime); var mapEnd = StrainSolverData.Max(s => Math.Max(s.StartTime, s.EndTime)); + var l = 0; + var r = 0; + while (l < StrainSolverData.Count && StrainSolverData[l].StartTime < mapStart) + l++; for (var i = mapStart; i < mapEnd; i += binSize) { - var valuesInBin = StrainSolverData.Where(s => s.StartTime >= i && s.StartTime < i + binSize).ToList(); + while (r < StrainSolverData.Count - 1 && StrainSolverData[r + 1].StartTime < i + binSize) + r++; + if (l >= StrainSolverData.Count) + break; + + var valuesInBin = StrainSolverData.GetRange(l, r - l + 1); var averageRating = valuesInBin.Count > 0 ? valuesInBin.Average(s => s.TotalStrainValue) : 0; bins.Add(averageRating); + l = r + 1; } if (!bins.Any(strain => strain > 0)) return 0; From 203bb4f75b541f4cc6f1056507e6c33db4074413 Mon Sep 17 00:00:00 2001 From: WilliamQiufeng Date: Sun, 18 Aug 2024 15:08:15 +0800 Subject: [PATCH 2/4] Pad 0 to bins if l >= StrainSolverData.Count, instead of breaking the loop --- .../Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs index b0935ce0f..1a6c4af70 100644 --- a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs +++ b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs @@ -569,7 +569,10 @@ private float CalculateOverallDifficulty() while (r < StrainSolverData.Count - 1 && StrainSolverData[r + 1].StartTime < i + binSize) r++; if (l >= StrainSolverData.Count) - break; + { + bins.Add(0); + continue; + } var valuesInBin = StrainSolverData.GetRange(l, r - l + 1); var averageRating = valuesInBin.Count > 0 ? valuesInBin.Average(s => s.TotalStrainValue) : 0; From d2e72413d31ed440998dde24980f2f9693d7213b Mon Sep 17 00:00:00 2001 From: WilliamQiufeng Date: Sun, 18 Aug 2024 15:32:46 +0800 Subject: [PATCH 3/4] Use fallback method (O(n^2)) when keycount != 4 to address bug #181 --- .../Rulesets/Keys/DifficultyProcessorKeys.cs | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs index 1a6c4af70..b846bb770 100644 --- a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs +++ b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs @@ -562,19 +562,30 @@ private float CalculateOverallDifficulty() var l = 0; var r = 0; + var useFallback = Map.GetKeyCount() != 4; while (l < StrainSolverData.Count && StrainSolverData[l].StartTime < mapStart) l++; for (var i = mapStart; i < mapEnd; i += binSize) { - while (r < StrainSolverData.Count - 1 && StrainSolverData[r + 1].StartTime < i + binSize) - r++; - if (l >= StrainSolverData.Count) + List valuesInBin; + if (useFallback) { - bins.Add(0); - continue; + valuesInBin = StrainSolverData.Where(s => s.StartTime >= i && s.StartTime < i + binSize) + .ToList(); + } + else + { + while (r < StrainSolverData.Count - 1 && StrainSolverData[r + 1].StartTime < i + binSize) + r++; + if (l >= StrainSolverData.Count) + { + bins.Add(0); + continue; + } + + valuesInBin = StrainSolverData.GetRange(l, r - l + 1); } - var valuesInBin = StrainSolverData.GetRange(l, r - l + 1); var averageRating = valuesInBin.Count > 0 ? valuesInBin.Average(s => s.TotalStrainValue) : 0; bins.Add(averageRating); From b4481a39104616fbb7b19b308df228f4c20186b3 Mon Sep 17 00:00:00 2001 From: WilliamQiufeng Date: Mon, 19 Aug 2024 00:07:28 +0800 Subject: [PATCH 4/4] Apply requested refactorings l -> leftIndex r -> rightIndex useFallback is only enabled on odd key count (not counting scratch) --- .../Rulesets/Keys/DifficultyProcessorKeys.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs index b846bb770..349ef6488 100644 --- a/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs +++ b/Quaver.API/Maps/Processors/Difficulty/Rulesets/Keys/DifficultyProcessorKeys.cs @@ -560,11 +560,11 @@ private float CalculateOverallDifficulty() var mapStart = StrainSolverData.Min(s => s.StartTime); var mapEnd = StrainSolverData.Max(s => Math.Max(s.StartTime, s.EndTime)); - var l = 0; - var r = 0; - var useFallback = Map.GetKeyCount() != 4; - while (l < StrainSolverData.Count && StrainSolverData[l].StartTime < mapStart) - l++; + var leftIndex = 0; + var rightIndex = 0; + var useFallback = Map.GetKeyCount(false) % 2 == 1; + while (leftIndex < StrainSolverData.Count && StrainSolverData[leftIndex].StartTime < mapStart) + leftIndex++; for (var i = mapStart; i < mapEnd; i += binSize) { List valuesInBin; @@ -575,21 +575,22 @@ private float CalculateOverallDifficulty() } else { - while (r < StrainSolverData.Count - 1 && StrainSolverData[r + 1].StartTime < i + binSize) - r++; - if (l >= StrainSolverData.Count) + while (rightIndex < StrainSolverData.Count - 1 && StrainSolverData[rightIndex + 1].StartTime < i + binSize) + rightIndex++; + + if (leftIndex >= StrainSolverData.Count) { bins.Add(0); continue; } - valuesInBin = StrainSolverData.GetRange(l, r - l + 1); + valuesInBin = StrainSolverData.GetRange(leftIndex, rightIndex - leftIndex + 1); } var averageRating = valuesInBin.Count > 0 ? valuesInBin.Average(s => s.TotalStrainValue) : 0; bins.Add(averageRating); - l = r + 1; + leftIndex = rightIndex + 1; } if (!bins.Any(strain => strain > 0)) return 0;