微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在MS-Word自动化中C#比C ++更快

如何解决为什么在MS-Word自动化中C#比C ++更快

我写了一个小测试,将C#和C ++进行比较,每个人执行相同的动作需要1000次。操作是获取Pages.Count

这是测试代码

public void Main()
{
    TestCppVsCs();
}

[DllImport("WordWithCpp.dll",CallingConvention = CallingConvention.Cdecl,SetLastError = true)]
extern static long Test(IntPtr pWordIUnkNown);

private void TestCppVsCs()
{
    Console.WriteLine($"Cpp: {TestCpp()}");
    Console.WriteLine($"C#:  {TestCs()}");
    Console.ReadLine();
}

private long TestCpp()
{
    var word = GetWordApp();
    return Test(Marshal.GetIUnkNownForObject(word));
}

private double TestCs()
{
    var word = GetWordApp();

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    // Do the action 1000 times
    for (var I = 1; I <= 1000; I++)
        var Count = word.ActiveDocument.ActiveWindow.ActivePane.Pages.Count;

    stopwatch.Stop();

    return stopwatch.Elapsed.TotalMilliseconds;
}

public Word.Application GetWordApp()
{
    try
    {
        return Marshal.GetActiveObject("Word.Application");
    }
    catch (Exception ex)
    {
        return new Word.Application();
    }
}

这就是C ++代码

#include <stdio.h>
#include <windows.h>

#import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" \
    rename("RGB","MSORGB") \
    rename("DocumentProperties","MSodocumentProperties")
using namespace Office;

#import "libid:0002E157-0000-0000-C000-000000000046"
using namespace VBIDE;

#import "libid:00020905-0000-0000-C000-000000000046" \
    rename("Exitwindows","WordExitwindows") \
    rename("FindText","WordFindText")

#define DllExport  extern "C" __declspec(dllexport)

// from https://stackoverflow.com/a/23527229/7206675
#include <iostream>
#include <chrono>
namespace cr = std::chrono;

DllExport LONGLONG Test(IUnkNown* iUnkNown) {
    
    typedef cr::high_resolution_clock my_clock;    
    auto spWordApp = static_cast<Word::_ApplicationPtr>(iUnkNown);
    auto start_time = my_clock::Now();

    // Do the action 1000 times
    for (size_t i = 0; i < 1000; i++)
    {
        auto Count = spWordApp->ActiveDocument->ActiveWindow->ActivePane->Pages->Count;
    }

    // get the clock time after the operation
    auto end_time = my_clock::Now();

    // get the elapsed time
    auto diff = end_time - start_time;

    // convert from the clock rate to a millisecond clock
    auto milliseconds = cr::duration_cast<cr::milliseconds>(diff);

    // get the clock count (i.e. the number of milliseconds)
    auto millisecond_count = milliseconds.count();

    return millisecond_count;
}

结果是:

Cpp: 2812
C#:  1554.2814

解释是什么,为什么C ++的速度是C#的两倍?

我希望看到C ++更快,因为MS-Word COM也用C ++编写。

我在发布时都编译了两个项目

C ++项目位于Win32平台中,并使用以下命令行在VS 2019中进行编译:

/允许的-/ GS / GL /分析-/ W3 / Gy / Zc:wchar_t / Qspectre / Zi / Gm- / O2 / sdl /Fd"Release\vc142.pdb“ / Zc:inline / fp:precise / D” WIN32“ / D “ NDEBUG” / D“ _CONSOLE” / D“ _WINDLL” / D“ _UNICODE” / D“ UNICODE” / errorReport:提示/ WX- / Zc:forScope / Gd / Oy- / Oi / MD / FC / Fa“发布” / EHsc / nologo / Fo“发布” / Fp“发布\ WordWithCpp.pch” / diagnostics:column

.Net项目是4.6.2框架版本,并且x86是目标cpu

解决方法

您的C ++在#importauto->后面隐藏了大量魔术。 C#和CLR中的相应魔术可能会更聪明。 Office界面通常是IDispatch界面,因此有很多机会来缓存DispId列表以及沿途收集的类似信息。如果您开始追求细节,那将是一个深深的兔子洞。 Adam Nathan's .NET and COM book的1579页只是一个开始。在我看来,对于COM互操作方案(以及一般而言),性能并不是使用C ++而不是.NET的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。