我如何在PerfView中看到昂贵的方法

Mat*_*s F 3 performance .net-4.0 perfview

我创建了一个简单的控制台应用程序,并通过Run Command - > PerfMonTest.exe从PerfView执行它

我得到日志文件,看看应用程序的过程.如预期的那样昂贵(99%CPU),但是当我想深入研究昂贵的方法时,它们不会显示在昂贵的方法列表中.

我能做些什么让它们可见吗?

这是我选择过程时的视图.我希望列表中有CallExpensive和CallCheap:

在此输入图像描述

选择主要方法并不能让我进一步深入研究被调用的方法

在此输入图像描述

这是应用程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PerfMonTest
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i <= 2000; i++)
            {
                CallExpensive(1000);
                CallCheap(1000);
                CallCheap(400);
            }

        }

        public static void CallExpensive(int expense)
        {
            for (int i = 0; i <= expense; i++)
            {
                DateTime checkTime = DateTime.Now;
                string val = "10" + i.ToString();
            }
        }

        public static void CallCheap(int expense)
        {
            for (int i = 0; i <= expense; i++)
            {
                int j = 2;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*sen 5

从截图来看,你没有加载符号.如果你这样做,你会发现大部分时间都花在了DateTime.Now.

如果Main在" 按名称"视图中单击,您将转到" 调用者"视图,该视图将告诉您调用哪些方法Main.如果要深入研究Main调用的方法,则需要转到" 被调用者"视图.如果你这样做,你会看到打破了什么Main电话.

但是,在这种特殊情况下,逻辑CallExpensiveCallCheap如此简单,方法将被内联(在发布模式下).因为这些方法是内联的,所以它们不会Main作为代码被折叠成Main自身的调用的一部分出现.

您可以通过在方法运行后附加调试器来验证方法是否内联,并查看该类型的方法描述符.这是我得到的输出:

0:004> !dumpmt -md 004737c0
EEClass:         00471278
Module:          00472e94
Name:            ConsoleApplication1.Program
mdToken:         02000002
File:            C:\temp\ConsoleApplication1\ConsoleApplication1\bin\Release\ConsoleApplication1.exe
BaseSize:        0xc
ComponentSize:   0x0
Slots in VTable: 8
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
   Entry MethodDe    JIT Name
72064a00 71d66728 PreJIT System.Object.ToString()
72058830 71d66730 PreJIT System.Object.Equals(System.Object)
72058400 71d66750 PreJIT System.Object.GetHashCode()
72051790 71d66764 PreJIT System.Object.Finalize()
0047c01d 004737b8   NONE ConsoleApplication1.Program..ctor()
004d0050 00473794    JIT ConsoleApplication1.Program.Main(System.String[])
0047c015 004737a0   NONE ConsoleApplication1.Program.CallExpensive(Int32)
0047c019 004737ac   NONE ConsoleApplication1.Program.CallCheap(Int32)

这样的事实CallExpensive,并CallCheapNONE在JIT列中列出表明他们内联(或不叫所有,但这里并非如此).