MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как узнать какой метод больше загружает процессор?"
Answer 799280
Для получения процессорного времени, затраченного на выполнение однопоточного метода, необходимо вычесть значения ProcessThread.TotalProcessorTime после и до выполнения метода. Соответственно, загрузку процессора (среднюю), создаваемую в ходе его выполнения, можно найти, разделив полученное значение на
Environment.ProcessorCount * ВремяВыполнения
. Для повышения точности расчетов произвести измерение несколько раз и найти среднее. Пример:using System; using System.Collections.Generic; using System.Data; using System.Text; using System.Diagnostics; using System.Threading; namespace ConsoleTest1 { class Program { /* Измеряемый метод */ public static Int64 DoSomething(Int64 x) { Int64 res = 1; for (Int64 i = 1; i <= x; i++) res += i; return res; } [System.Runtime.InteropServices.DllImport("kernel32.dll")] static extern uint GetCurrentThreadId(); const int N = 50; //число итераций static void Main(string[] args) { Console.WriteLine(DoSomething(5000000).ToString()); //прогрев Int64 sum=0; Stopwatch sw = new Stopwatch(); var id = GetCurrentThreadId();//получаем ID текущего потока Process pr = Process.GetCurrentProcess(); ProcessThread thread = null; //находим объект ProcessThread для текущего потока foreach (ProcessThread th in pr.Threads) { if (th.Id == (int)id) thread = th; } if (thread == null) { Console.WriteLine("ProcessThread not found"); return; } sw.Start();//начало измерений var before = thread.TotalProcessorTime.Ticks; for (int i = 0; i < N; i++) { sum += DoSomething(50000000);//вызов измерямого метода } Console.WriteLine(sum.ToString()); var after = thread.TotalProcessorTime.Ticks; sw.Stop();//конец измерений double processor_time = TimeSpan.FromTicks(after - before).TotalMilliseconds / N; double total_time = (sw.ElapsedMilliseconds) / (double)N; double usage = (processor_time) / (Environment.ProcessorCount * total_time) * 100.0; Console.WriteLine("Processor time:" + Math.Round(processor_time,2).ToString()); Console.WriteLine("Total time:" + total_time.ToString()); Console.WriteLine("Usage %:" + Math.Round(usage,1).ToString()); } } }
Если DoSomething выполняет только голые вычисления, без обращения к вводу/выводу или ожидания событий, значение загрузки будет близко к
100% / Environment.ProcessorCount
. Если он содержит вызов Thread.Sleep, загрузка будет близка к нулю. Все остальное - что-то посередине.Если метод многопоточный, нужно либо суммировать по всем задействованным потокам, либо просто брать Process.TotalProcessorTime для грубого приближения (в предположении, что ничего другого в данный момент в процессе не происходит).
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.