C# 内存分配时间(快速方式)
对于一个非常简单的代码片段,我试图了解在小对象堆(SOH)上实际分配对象花费了多少时间 由于这是一个发布版本,死代码消除可能会起作用,所以WinDbg用于检查最终的机器代码 产生的JITed代码,其主循环在下面以蓝色突出显示,它只是重复装箱,表明处理内存分配的方法不是内联的(注意,C# 内存分配时间(快速方式),c#,.net,profiling,clr,C#,.net,Profiling,Clr,对于一个非常简单的代码片段,我试图了解在小对象堆(SOH)上实际分配对象花费了多少时间 由于这是一个发布版本,死代码消除可能会起作用,所以WinDbg用于检查最终的机器代码 产生的JITed代码,其主循环在下面以蓝色突出显示,它只是重复装箱,表明处理内存分配的方法不是内联的(注意,调用到hex address00af30f4): 此方法反过来尝试通过“快速”方式分配,如果失败,则返回到调用到JIT_New本身的“慢速”方式): 有趣的是,从上述代码获得的PerfView中的调用堆栈没有显示M
调用
到hex address00af30f4
):
此方法反过来尝试通过“快速”方式分配,如果失败,则返回到调用到JIT_New
本身的“慢速”方式):
有趣的是,从上述代码获得的PerfView中的调用堆栈没有显示Main
级别和JIT\u New
条目本身之间的任何中间方法(假设Main
没有直接调用JIT\u New
):
我想知道为所有装箱的文件分配空间花费了多少时间
。。。你不能用秒表吗?在object o=currentNumber之前启动它代码>然后在对象o=currentNumber后停止代码>。完成后,查看ElapsedTicks
属性。。。然后使用Frequency
字段将这些滴答声转换为实际秒数(如果需要)。我认为GC正在启动,包括阻塞和背景(至少对于gen0/1)都可能会扭曲结果。另一方面,调用堆栈不会说谎——只要它们被频繁使用——但是如果没有为慢路径调用函数,那么就真的没有什么可看的。是的,这肯定是一种可能性,但是TMK我不确定如何避免这种情况。也许其他人可以插话。@MihaiAlbert:呼叫堆栈肯定会撒谎。“JIT_TrialAllocSFastMP”方法可能是内联的。@Idov:我已经用WinDbg进行了检查,但它似乎没有内联。我还用我的最新发现更新了这个问题。我想知道为所有盒装文件分配空间花费了多少时间。
。。。你不能用秒表吗?在object o=currentNumber之前启动它代码>然后在对象o=currentNumber后停止代码>。完成后,查看ElapsedTicks
属性。。。然后使用Frequency
字段将这些滴答声转换为实际秒数(如果需要)。我认为GC正在启动,包括阻塞和背景(至少对于gen0/1)都可能会扭曲结果。另一方面,调用堆栈不会说谎——只要它们被频繁使用——但是如果没有为慢路径调用函数,那么就真的没有什么可看的。是的,这肯定是一种可能性,但是TMK我不确定如何避免这种情况。也许其他人可以插话。@MihaiAlbert:呼叫堆栈肯定会撒谎。“JIT_TrialAllocSFastMP”方法可能是内联的。@Idov:我已经用WinDbg进行了检查,但它似乎没有内联。我也用我的最新发现更新了这个问题。
static void Main(string[] args)
{
const int noNumbers = 10000000; // 10 mil
ArrayList numbers = new ArrayList();
Random random = new Random(1); // use the same seed as to make
// benchmarking consistent
for (int i = 0; i < noNumbers; i++)
{
int currentNumber = random.Next(10); // generate a non-negative
// random number less than 10
object o = currentNumber; // BOXING occurs here
numbers.Add(o);
}
}
const int noNumbers = 10000000; // 10 mil
object o = null;
for (int i=0;i<noNumbers;i++)
{
o = i;
}