从C ++ / CX Windows运行时组件实例化WinRT对象时,性能不佳

时间:2018-06-25 07:49:44

标签: performance windows-runtime instantiation c++-cx

我发现从C ++ / CX Windows运行时组件实例化WinRT对象会降低性能,并且我不知道问题是由于C ++ / CX项目中的配置错误还是因为编译器中的问题(我m使用Visual Studio 2017 v15.7.4)。

我已经创建了一个带有简单示例的存储库来测试性能损失:https://github.com/joseangelmt/UWP-CPP_CX-PERFORMANCE-ISSUES,但我将在此处进行解释:

该存储库包含一个应用程序,该应用程序用于测量从C#和C ++ / CX Windows运行时组件实例化WinRT对象的性能。

解决方案中包含三个项目:

  • PerformanceTest(C#UWP应用程序)。
  • WindowsRuntimeComponent1(公开空的Class1类的C ++ / CX WRC)。
  • WindowsRuntimeComponent2(C ++ / CX WRC,使用静态方法公开工厂,该方法返回一个新的WindowsRuntimeComponent1.Class1对象。

WindowsRuntimeComponent1中的Class1实现很简单:

namespace WindowsRuntimeComponent1
{
    public ref class Class1 sealed
    {
    public:
        Class1() {}
    };
}

,WindowsRuntimeComponent2中的工厂也很简单:

namespace WindowsRuntimeComponent2
{
    public ref class Factory sealed
    {
    public:
        static WindowsRuntimeComponent1::Class1^ CreateObject()
        {
            return ref new WindowsRuntimeComponent1::Class1();
        }

        static WindowsRuntimeComponent1::Class1^ CreateNullObject()
        {
            return nullptr;
        }
    };
}

运行应用程序时,您有一个按钮来开始测试。当您按下按钮时,将开始三个测试:

  • 直接从C#创建10000个WindowsRuntimeComponent1.Class1对象。由于WindowsRuntimeComponent1是C ++ / CX项目,因此存在跨边界操作。

        var list = new List<Class1>();
        for (int i = 0; i < 100000; i++)
            list.Add(new Class1());
    
  • 使用工厂WindowsRuntimeComponent2.Factory间接创建10000个WindowsRuntimeComponent1.Class1对象,因此也存在从应用程序到WindowsRuntimeComponent2的跨边界操作,因此由于跨边界操作而导致的性能降低应该相同。 / p>

        var list = new List<Class1>();
        for (int i = 0; i < 100000; i++)
            list.Add(Factory.CreateObject());
    
  • 从WindowsRuntimeComponent2.Factory创建10000个“空”对象,因此也存在从应用程序到WindowsRuntimeComponent2的跨边界操作,但是没有任何实例化。

        var list = new List<Class1>();
        for (int i = 0; i < 100000; i++)
            list.Add(Factory.CreateNullObject());
    

结果是,在我的计算机上,第一次测试大约需要 0.39秒完成,而第二次测试大约需要 25秒。第三次测试大约是 0.06秒,因此在跨边界时不会造成性能损失,而在使用ref new从C ++ / CX组件实例化对象时,性能不会受到影响。

我知道ref new为您隐藏了很多工作,但是从C#角度来看应该是相同的(实例化工厂对象,创建对象,QueryInterface等),所以我不敢相信这种性能损失从C ++ / CX实例化对象是正常的。

0 个答案:

没有答案