Из-за чего одинаковые делегаты работают по разному, В 10 Раз разница в скорости?

Ссылка скопирована
C#
0 ответов

По вводным: что за ерунда наблюдается.
По вводным: в примере создаются 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 ms

Test func: b__1
Count invoke: 55555
Standard deviation: 0.0091 ms
Max: 0.4715 ms
Min: 0.0355 ms
Mean time : 0.0420 ms

Test func: b__2
Count invoke: 3902
Standard deviation: 0.0589 ms
Max: 0.9081 ms
Min: 0.3880 ms
Mean : 0.4358 ms

Test func: b__2
Count invoke: 6124
Standard deviation: 0.0519 ms
Max: 0.7931 ms
Min: 0.3880 ms
Mean : 0.4263 ms

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно