【问题标题】:Managed C++ vs C# Performance for CodeModel and other COM ObjectsCodeModel 和其他 COM 对象的托管 C++ 与 C# 性能
【发布时间】:2009-08-08 21:59:08
【问题描述】:

我正在为 Visual Studio 2008 创建一个扩展,并且因为我不想为 C++ 编写自己的解析器(我不是自虐狂),所以我正在使用 VCCodeModel。

从这些 COM 对象中获取一个简单的字段比我正在执行的任何其他操作花费的时间要多几个数量级,而且由于我正在深入到非常大的 C++ 项目的方法级别,因此我在最低级别时效率低下我的递归。

   vcCodeBaseFunctions = ((Microsoft.VisualStudio.VCCodeModel.VCCodeElements)
                                (vcCM.Functions));
   int i = 0;
   for (i = 1; i <= vcCodeBaseFunctions.Count; i++)
   {
     if (vcCodeBaseFunctions.Item(i).Kind == vsCMElement.vsCMElementFunction)
                parent.AppendChild(MethodWrapper.VCCodeFunctionToXML(
                          (VCCodeFunction)vcCodeBaseFunctions.Item(i)));
   }

前面的代码将遍历项目基础级别的所有函数,将它们转换为 XML,然后保存它们。 XML 方法会调用 VCCodeFunction 中的多个字段,例如名称、参数等。

为此,托管 C++ 是否比 C# 更快?我对托管 C++ 的后端与 C# 的不同之处了解不足,但我的直觉会让我相信 C++ 中托管代码和非托管代码之间的“上下文切换”成本较少,但我错了吗?由于我认为使用 CodeModel 在 C++ 中的托管代码和非托管代码之间反复切换,我的速度有所放缓,所以我假设托管 C++ 会更快是正确的吗?

【问题讨论】:

    标签: c# visual-studio-2008 com managed-c++


    【解决方案1】:

    .NET 中的 COM 互操作层存在开销。如果您使用 C++,您可以将您的 COM 访问转移到本机代码中,这将加速该部分的代码访问。

    但是,如果您打算使用 C++/CLI,那么在某些时候您仍将拥有本地->托管互操作。在链中的某个地方,您将跨数据编组,尽管如果您可以将其移到这些循环之外,您可能会更快一些(如果您将递归设为 100% 本机,则互操作调用会少得多)。

    话虽如此,VCCodeModel 并不是特别快 - 尽管我同意您在 COM 互操作方面获得了一些开销,但请注意您使用的分析器可能夸大了这一点。如果您使用的是跟踪分析器,则尤其如此,因为与实际发布运行期间相比,在分析期间您将在这些调用中花费更多时间。探查器并不完美,这可能是由于探查器导致您的结果出现偏差的情况。

    我怀疑你的潜在速度提升不值得一个端口 - 尽管如果没有更多信息很难确定。

    【讨论】:

    • 您能否更具体地说明“跟踪分析器”如何扭曲分析结果?如果我告诉你我在最低级别的递归中对 COM 对象数据成员进行了大约十几个调用,你相信这会有什么不同吗?提取所有相关字段的大型 C++ 项目的每种方法?这似乎是 COM 互操作阻碍的情况,但我不确定。
    • 阅读跟踪与采样分析器,了解所有分析器如何扭曲结果的详细信息。最大的问题是他们必须完全禁用 JIT 的优化和内联,并且每个方法调用都会减慢速度。对你来说,使用原生 C++ 肯定会更快——但问题是多快。我希望您会看到非常小的增益,因此这完全取决于您对速度增益的需求程度。优化几乎总是工作/需求与收益之间的平衡——当前情况有多糟糕,你能真正改善多少,需要付出多少努力?
    • 是的,这是有道理的。您回答了我的问题,但不是“我可以保证 codemodel 在本机 C++ 中是 10 倍!”我希望。
    • 是的 - 对不起。不幸的是,这在很大程度上取决于您对代码模型所做的事情、如何调用它等等。跨 COM 互操作层的调用比托管->托管或本机->本机调用更昂贵 - 有一个成本。这不一定是一笔巨大的成本。
    • 我想我仍然会尝试这个 C++ 版本,因为在我使用 VCCodeModel 浏览的大型 C++ 项目中,对于每个方法,许多 COM 互操作都发生在递归的最低级别。我可能只是要制作一个 C++ dll 来处理方法处理,然后从 C# 调用它。代码模型的浏览仍然会出现 COM 互操作问题,但与处理方法所花费的时间相比,这是微不足道的。再次感谢您的帮助。
    【解决方案2】:

    与代码模型的速度相比,插件/包语言的速度没有。编辑:好吧,也许我过火了,但说真的,这里的第一句话是正确的。

    【讨论】:

    • 我并不是说代码模型不快。我要说的是从 COM 代码模型对象访问字段几乎占用了所有处理器时间(我已经在 ANTS 中分析了这个插件)。我目前正在使用 C#,想知道托管 C++ 是否会更快。
    【解决方案3】:

    C++ 不太可能更快。

    编写自己的解析器可能执行更快。当然,编写自己的解析器可能需要更长的时间。

    【讨论】:

    • 难道不能更轻松地从托管 C++ 引用非托管代码吗? .NET 框架和非托管代码之间的“上下文切换”在 C++ 下是否有任何不同,或者这只是语法糖的区别?
    猜你喜欢
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 2020-05-03
    • 2010-12-28
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多