首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AggressiveInlining什么时候可以在简单的包装器上应用?

AggressiveInlining什么时候可以在简单的包装器上应用?
EN

Stack Overflow用户
提问于 2013-07-25 07:08:29
回答 2查看 1.3K关注 0票数 1

当我简单地包装一个AggressiveInlining调用时,我无法看到DataStructure的效果

例如:

代码语言:javascript
复制
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);
   }
}

然后做这个

代码语言:javascript
复制
    //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,则数字保持不变。

函数调用的性能成本仍然存在。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-25 08:07:09

秒表不是评估代码是否被内联的正确工具。它只是提供了一个性能度量。

首先,要使代码内联,必须在启用优化的情况下执行构建。使用Visual最简单的方法是使用发行版构建。调试版本不会由JITter进行优化,因此不会有任何内容被内联。要查看代码是否已被JITter内联,建议您附加调试器并比较调试生成和发行版构建之间的反汇编。如果一个电话是内联的,那么你会注意到一个不同的地方。

在您的示例中,对应于callWList.Put()程序集指令将消失在发布版本中,并被对应于ArrayList.Add()call程序集指令所取代。

值得一提的是,默认情况下,当您将Visual调试器附加到任何构建时,它将抑制优化以允许您正确地执行代码的每一行。要关闭这个选项,您需要取消在Tools -> Options -> Debugging -> General中找到的“在模块加载上抑制JIT优化”选项。

第二,回答你的实际问题。该方法不会内联,因为它是虚拟的。请参阅下面的博文。

http://blogs.msdn.com/b/davidnotario/archive/2004/11/01/250398.aspx

“以下是我们不采用一种方法的原因:

  • 虚拟呼叫:我们不会在虚拟呼叫之间内联。不这样做的原因是我们不知道呼叫的最终目标。我们在这里可能会做得更好(例如,如果99%的调用最终位于同一个目标中,您可以生成对虚拟调用将要执行的对象的方法表进行检查的代码,如果不是99%的情况,则执行调用,否则只执行内联代码),但与J语言不同的是,我们支持的主要语言中的大多数调用都不是虚拟的,因此我们不必太积极地优化这种情况。“

虽然这篇文章有近10年的历史,但我不认为这一点在以后的任何JIT编译器中都没有改变。

票数 5
EN

Stack Overflow用户

发布于 2013-07-25 07:57:01

由于您的方法是虚拟的,所以JIT编译器不会内联虚拟调用,请阅读此论坛以获得更多信息。另外,为了确保方法是内联的,您可以:

检查System.Reflection.MethodBase.GetCurrentMethod().Name.如果方法是内联的,它将返回调用方的名称。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17851260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档