C#与C++混合编程及性能分析

简介: C#与C++混合编程及性能分析

概要:


 众所周知,用C#做界面比C++开发效率要高得多,但在有性能问题的情况下不得不将部分模块使用C++,这时就需要使用C#与C++混合编程。本文给出了两种混合编程的方法以及性能对比。


开发环境:


 I5-8400 CPU 2.8G 8G,Win10 64Bit,VS2017(C++开发设置),C++,C#都采用x32平台,性能验证使用Release版本。


测试纯C++项目性能:

 1. 新建空解决方案:文件|新建|项目|已安装|模板|其他项目类型|Visual Studio解决方案|空白解决方案


 2. 新建C++项目:右击解决方案|添加|新建项目|已安装|Visual C++|Win32控制台程序,按缺省设置生成项目


 3. 在配置管理器中新建x32平台,删除其他平台


 4. 新建CppFunction,并添加测试代码,完整代码如下,程序结果:Result: 1733793664 Elapsed:65


// CppFunction.h


#pragma once


class CppFunction


{


public:


   CppFunction(){}


   ~CppFunction(){}


   int TestFunc(int a, int b);


};


// CppFunction.cpp


#include "stdafx.h"


#include "CppFunction.h"


class CCalc


{


public:


   CCalc(int a, int b)


   {


       m_a = a;


       m_b = b;


   }


   int Calc()


   {


       if (m_a % 2 == 0){


           return m_a + m_b;


       }


       if (m_b % 2 == 0){


           return m_a - m_b;


       }


       return m_b - m_a;


   }


private:


   int m_a;


   int m_b;


};


int CppFunction::TestFunc(int a, int b)


{


   CCalc calc(a, b);


   return calc.Calc();


}


// PureCpp.cpp : 定义控制台应用程序的入口点。


//


#include "stdafx.h"


#include <iostream>


#include <windows.h>


#include "CppFunction.h"


using namespace std;


int _tmain(int argc, _TCHAR* argv[])


{


   DWORD start = ::GetTickCount();


   CppFunction cppFunction;


   int result = 0;


   for (int i = 0; i < 10000; i++){


       for (int j = 0; j < 10000; j++){


           result += cppFunction.TestFunc(i, j);


       }


   }


   DWORD end = ::GetTickCount();


   cout << "Result: " << result << " Elapsed: " << end - start << endl;


   return 0;


}

tt.png

测试纯Csharp项目性能:

 1. 新建PureCsharp项目:右击解决方案|添加|新建项目|已安装|其他语言|Visual C#|控制台应用程序,按缺省设置生成项目


 2. 在配置管理器中新建x32平台,删除其他平台,去掉【创建新的解决方案平台】勾选,否则会报x32平台已经存在


 3. 将C++项目中的代码复制过来稍作改动,完整代码如下,程序结果:Result: 1733793664 Elapsed: 607


using System;


using System.Collections.Generic;


using System.Linq;


using System.Text;


using System.Threading.Tasks;


namespace PureCsharp


{


   class CCalc


   {


       public CCalc(int a, int b)


       {


           m_a = a;


           m_b = b;


       }


       public int Calc()


       {


           if (m_a % 2 == 0)


           {


               return m_a + m_b;


           }


           if (m_b % 2 == 0)


           {


               return m_a - m_b;


           }


           return m_b - m_a;


       }


       private int m_a;


       private int m_b;


   }


   class CppFunction


   {


       public int TestFunc(int a, int b)


       {


           CCalc calc = new CCalc(a, b);


           return calc.Calc();


       }


   }


   class Program


   {


       static void Main(string[] args)


       {


            DateTime start = System.DateTime.Now;


           CppFunction cppFunction = new CppFunction();


           int result = 0;


           for (int i = 0; i < 10000; i++){


               for (int j = 0; j < 10000; j++){


                   result += cppFunction.TestFunc(i, j);


               }


           }


           DateTime end = System.DateTime.Now;


           System.Console.WriteLine("Result: " + result + " Elapsed: " + (end - start).Milliseconds);


      }


   }


}


tt.png

性能分析:


 从上面的对比可以看出,同样的功能,C#的耗时几乎是C++的10倍,这个例子里的主要原因是,C++可以使用高效的栈内存对象(CCalc),而C#所有对象只能放在托管堆中。


托管C++混合方式:

 1. 新建C#控制台项目,命名为CSxingneng,使用它来调用C++项目,修改生成目录为:..\x32\Release\


 2. 在CLR中,新建CLR C++DLL项目,命名为C++1。


 3. 在C++1中添加CppFunction类,并复制代码,完整代码如下,程序结果:Result: 1733793664 Elapsed: 325


// CppFunction.h


#pragma once


public ref class CppFunction


{


public:


   CppFunction(){}


   ~CppFunction(){}


   int TestFunc(int a, int b);


};


// CppFunction.cpp


#include "CppFunction.h"


class CCalc


{


public:


   CCalc(int a, int b)


   {


       m_a = a;


       m_b = b;


   }


   int Calc()


   {


       if (m_a % 2 == 0){


           return m_a + m_b;


       }


       if (m_b % 2 == 0){


           return m_a - m_b;


       }


       return m_b - m_a;


   }


private:


   int m_a;


   int m_b;


};


int CppFunction::TestFunc(int a, int b)


{


   CCalc calc(a, b);


   return calc.Calc();


}


using System;


using System.Collections.Generic;


using System.Linq;


using System.Text;


using System.Threading.Tasks;



namespace CSxingneng


{


   class Program


   {


       static void Main(string[] args)


       {


           DateTime start = System.DateTime.Now;


           CppFunction cppFunction = new CppFunction();


           int result = 0;


           for (int i = 0; i < 10000; i++)


           {


               for (int j = 0; j < 10000; j++)


               {


                   result += cppFunction.TestFunc(i, j);


               }


           }


           DateTime end = System.DateTime.Now;


           System.Console.WriteLine("Result: " + result + " Elapsed: " + (end - start).Milliseconds);


       }


   }


}


 tt.png

性能分析:


 使用混合编程后,性能得到了一定程度的提升,但比起单纯的C++项目,还是差了很多


 将C#主函数中的逻辑转移到C++1项目中,即添加如下的static方法,C#中只要调用该方法,程序结果:Result: 1733793664 Elapsed: 325


int CppFunction::Test()


{


   DWORD start = ::GetTickCount();


   CppFunction cppFunction;


   int result = 0;


   for (int i = 0; i < 10000; i++){


       for (int j = 0; j < 10000; j++){


           result += cppFunction.TestFunc(i, j);


       }


   }


   DWORD end = ::GetTickCount();


   cout << "Result: " << result << " Elapsed: " << end - start << endl;


   return result;


}


 并没有变得更快,估计是当使用【公共语言运行时支持】方式编译C++时,不能发挥C++的性能优势


DLLImport混合方式:

 1. 新建非空的C++DLL项目,命名为NativeDLLCpp


 2. 将CppFunction类从PureCpp中复制过来


 3. 代码如下,运行结果:Result: 1733793664 Elapsed: 75


// NativeDLLCpp.cpp : 定义 DLL 应用程序的导出函数。


//


#include "stdafx.h"


#include <iostream>


#include <windows.h>


#include "CppFunction.h"


using namespace std;


#ifdef __cplusplus


#define TEXPORT extern "C" _declspec(dllexport)


#else


#define TEXPORT _declspec(dllexport)


#endif


TEXPORT int Test()


{


   DWORD start = ::GetTickCount();


   CppFunction cppFunction;


   int result = 0;


   for (int i = 0; i < 10000; i++){


       for (int j = 0; j < 10000; j++){


           result += cppFunction.TestFunc(i, j);


       }


   }


   DWORD end = ::GetTickCount();


   cout << "C++ Result: " << result << " Elapsed: " << end - start << endl;


   return result;


}


   public class NativeDLLCpp


   {


       [DllImport("NativeDLLCpp.dll")]


       public static extern int Test();


   }


   class Program


   {


       static void Main(string[] args)


       {


           DateTime start = System.DateTime.Now;


           int result = NativeDLLCpp.Test();


           DateTime end = System.DateTime.Now;


           System.Console.WriteLine("Result: " + result + " Elapsed: " + (end - start).Milliseconds);


       }


}


tt.png


性能分析:

  跟纯C++项目性能几乎一致。

  项目依赖项需要手动设置。

  实现联调的方法:修改C#项目属性|调试|启用本机代码调试



目录
相关文章
|
7月前
|
算法 Unix Linux
【C/C++ 实用工具】性能分析工具一览
【C/C++ 实用工具】性能分析工具一览
328 0
|
7月前
|
数据处理 C# C++
如何使用C#和C++结构体实现Socket通信
如何使用C#和C++结构体实现Socket通信
334 0
|
C# 开发工具 C++
简单C#类转非托管C++
简单C#类转非托管C++
|
7月前
|
数据可视化 关系型数据库 编译器
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
1075 2
|
2月前
|
C++ Python
探索Python与C/C++混合编程的艺术
探索Python与C/C++混合编程的艺术
50 1
|
3月前
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
3月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
166 1
|
5月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
【7月更文挑战第28天】在 Android 开发中, NDK 让 Java 与 C++ 混合编程成为可能, 从而提升应用性能。**为何选 NDK?** C++ 在执行效率与内存管理上优于 Java, 特别适合高性能需求场景。**环境搭建** 需 Android Studio 和 NDK, 工具如 CMake。**JNI** 构建 Java-C++ 交互, 通过声明 `native` 方法并在 C++ 中实现。**实战** 示例: 使用 C++ 计算斐波那契数列以提高效率。**总结** 混合编程增强性能, 但增加复杂性, 使用前需谨慎评估。
152 4
|
6月前
|
Java Go C#
编程语言C#、C++、Java、Python、go 选择哪个好?
我想说的是,不论选择哪种编程语言,决定选择的都是你最终的目的,做选择之前,先充分调研每一个选择项,再做选择思路就会非常清晰了。
139 3