当我简单地包装一个AggressiveInlining调用时,我无法看到DataStructure的效果
例如:
public class WList
{
//made static just to check inlining
//otherwise inlining might not kick in since 'this' keyword will disallow it
static System.Collections.ArrayList list;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Put(object item)
{
WList.list.Add(item);
}
}然后做这个
//Add 1000000 number of items in the list
//Run this test many times
for (int j = 0; j < 100; j++)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < length; i++)
{
//ADD ITEMS IN A SIMPLE ARRAY LIST
arraylist.Add(emptyobject);
}
sw.Stop();
//clear the list
}
//Do similar test on wrapper
for (int j = 0; j < 100; j++)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < length; i++)
{
//ADD ITEMS IN ARRAY LIST THROUGH WRAPPER
wrapperList.Put(emptyobject);
}
sw.Stop();
//clear the list
}Inlinig基本上是用来展开函数并将内部代码放在外部的,但是包装器的数字比直接调用慢。
如果使用Hastable或使用get调用而不是add,则数字保持不变。
函数调用的性能成本仍然存在。
发布于 2013-07-25 08:07:09
秒表不是评估代码是否被内联的正确工具。它只是提供了一个性能度量。
首先,要使代码内联,必须在启用优化的情况下执行构建。使用Visual最简单的方法是使用发行版构建。调试版本不会由JITter进行优化,因此不会有任何内容被内联。要查看代码是否已被JITter内联,建议您附加调试器并比较调试生成和发行版构建之间的反汇编。如果一个电话是内联的,那么你会注意到一个不同的地方。
在您的示例中,对应于call的WList.Put()程序集指令将消失在发布版本中,并被对应于ArrayList.Add()的call程序集指令所取代。
值得一提的是,默认情况下,当您将Visual调试器附加到任何构建时,它将抑制优化以允许您正确地执行代码的每一行。要关闭这个选项,您需要取消在Tools -> Options -> Debugging -> General中找到的“在模块加载上抑制JIT优化”选项。
第二,回答你的实际问题。该方法不会内联,因为它是虚拟的。请参阅下面的博文。
http://blogs.msdn.com/b/davidnotario/archive/2004/11/01/250398.aspx
“以下是我们不采用一种方法的原因:
虽然这篇文章有近10年的历史,但我不认为这一点在以后的任何JIT编译器中都没有改变。
发布于 2013-07-25 07:57:01
由于您的方法是虚拟的,所以JIT编译器不会内联虚拟调用,请阅读此论坛以获得更多信息。另外,为了确保方法是内联的,您可以:
检查System.Reflection.MethodBase.GetCurrentMethod().Name.如果方法是内联的,它将返回调用方的名称。
https://stackoverflow.com/questions/17851260
复制相似问题