Из-за чего одинаковые делегаты работают по разному, В 10 Раз разница в скорости?
По вводным: что за ерунда наблюдается.
По вводным: в примере создаются 2 Одинаковых делегата(Ели ели нашел что в них дело, проверяя 1000 комбинаций причин), тот кто первый запустится будет в 10 раз быстрее. Почему так происходит, неожиданно поймал такое.
Сейчас ситуация такая: вот для простоты пример, замеряю работу функции, создал расширение For для выполнения N раз функции для элементов массивов, без него эффект не наблюдается, если допустим цикл внутрь m(()=>{for....}); вставить.
Сейчас ситуация такая: немного подебажил, и вроде заметил, что второй в порядке вызова метод вообще не инлайнится, и там прям стандартный метод вместо хотя бы 2 инструкций "lea lea eax, [rcx + rdx]; ret" там 10-20 как в debug режиме.
var arr=Enumerable.Range(0,1_000_000).Select(i=> (X:(uint)i, Y: 1u)).ToArray(); // от n не зависит, (кортеж артефакт поиска причины ) // одинаковые делегаты, второй в порядке вызывания будет до 10-100 раз медленнее!!!! var del = () => arr.For ((a) => test1(a.Item1, a.Item2)); var del2 = () => arr.For ((a) => test1(a.Item1, a.Item2)); m(del); // зависит от порядка вызова m(del2); // какая-то случ функция до 50 асемблерных строк всяких инструкций эффект наблюдается где-то static uint test1(uint i, uint j) { return i + j; } public static class ArrayExtensions{ public static void For <T>(this T[] arr, Action<T> func) { int len = arr.Length; foreach(var i in arr) { func(i); } } } public static void m(Action action, Action load = null) { Stopwatch sw = Stopwatch.StartNew(); load?.Invoke(); action(); load?.Invoke(); sw.Start(); action(); sw.Stop(); int n = (int)(5_000 / (sw.Elapsed.TotalMilliseconds + 0.001f)); if (n == 0) n = 1; List<double> times = new List<double>(); for (int i = 0; i < n; i++) { load?.Invoke(); sw.Restart(); action(); sw.Stop(); times.Add(sw.Elapsed.TotalMilliseconds); } double sum = times.Sum(); double average = sum / n; double err = Math.Sqrt(times.Aggregate(0.0, (acc, e) => acc += (e - average) * (e - average)) / (n - 1)); Console.WriteLine($"Test func: {action.Method.Name}"); Console.WriteLine($"Count invoke: {n}"); Console.WriteLine("Standard deviation: {0,20:f4} ms", err); Console.WriteLine("Max: {0,20:f4} ms", times.Max()); Console.WriteLine("Min: {0,20:f4} ms", times.Min()); var c1 = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Mean time : {0,20:f4} ms", average); Console.ForegroundColor = c1; Console.WriteLine(); }
Test func: b__1
Count invoke: 5803
Standard deviation: 0.0146 ms
Max: 0.3772 ms
Min: 0.0362 ms
Mean time : 0.0509 msTest func: b__1
Count invoke: 55555
Standard deviation: 0.0091 ms
Max: 0.4715 ms
Min: 0.0355 ms
Mean time : 0.0420 msTest func: b__2
Count invoke: 3902
Standard deviation: 0.0589 ms
Max: 0.9081 ms
Min: 0.3880 ms
Mean : 0.4358 msTest func: b__2
Count invoke: 6124
Standard deviation: 0.0519 ms
Max: 0.7931 ms
Min: 0.3880 ms
Mean : 0.4263 ms
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос