概要:

  众所周知,用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;

}

测试纯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);

}

}

}

性能分析:

  从上面的对比可以看出,同样的功能,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);

}

}

}

性能分析:

  使用混合编程后,性能得到了一定程度的提升,但比起单纯的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);

}

}

性能分析:

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

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

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

C#与C++混合编程及性能分析相关推荐

  1. golang(3)高质量编程与性能分析

    1. 编程原则 实际场景千变万化,各种语言各不相同,但是高质量编程遵循的原则是相通的. 简单性 消除"多余的复杂性",以简单清晰的逻辑写代码 不理解的代码无法修复改进 可读性 代码 ...

  2. Go 语言编程 — Profiling 性能分析

    目录 文章目录 目录 Profiling runtime MemStat GC pprof trace Profiling Golang 提供了友好的工程化支持,其中之一就是 Profiling(分析 ...

  3. c include 多层目录_python+C、C++混合编程的应用

    TIOBE每个月都会新鲜出炉一份流行编程语言排行榜,这里会列出最流行的20种语言. 排序说明不了语言的好坏,反应的不过是某个软件开发领域的热门程度.语言的发展不是越来越common,而是越来越专注领域 ...

  4. c++冒泡排序_python+C、C++混合编程的应用

    TIOBE每个月都会新鲜出炉一份流行编程语言排行榜,这里会列出最流行的20种语言. 排序说明不了语言的好坏,反应的不过是某个软件开发领域的热门程度.语言的发展不是越来越common,而是越来越专注领域 ...

  5. python后台开发性能问题_《Python高性能编程》——2.14 确保性能分析成功的策略-阿里云开发者社区...

    本节书摘来自异步社区<Python高性能编程>一书中的第2章,第2.14节,作者[美] 戈雷利克 (Micha Gorelick),胡世杰,徐旭彬 译,更多章节内容可以访问云栖社区&quo ...

  6. cuda编程性能 分析工具 nvprof的使用

    ubuntu环境上,安装cuda,会自动安装一些工具nvcc ,nvprof nvcc-gdb.... 1.编译生成可执行文件 2.nvprof ./test 可以把性能分析数据输出到文件中 nvpr ...

  7. Python高级-编程技巧-1.3 Python垃圾回收及性能分析

    目录 通过实例方法名字的字符串调用方法 经典的参数错误 内存与内存管理简介(了解) 内存是什么? 操作系统的内存管理 进程内的内存管理 内存分配 内存池机制 缓冲池机制 垃圾回收机制 介绍 OS模块 ...

  8. CUDA C编程接口技术分析

    CUDA C编程接口技术分析 编程接口 CUDA C为熟悉C编程语言的用户提供了一个简单的路径,可以方便地编写程序供设备执行. 它由C语言的最小扩展集和运行库组成. 核心语言扩展已经引入:cuda c ...

  9. i27岁转行java,JavaTM I/O 性能分析[转]

    JavaTM I/O 性能分析[转] 上一篇 / 下一篇  2008-07-30 13:04:44 / 个人分类:Zee的生活 这篇文章讨论和阐明了提供 JavaTM I/O 性能的多种设计问题,例如 ...

  10. Matlab与C/C++混合编程接口及应用

    http://www.cnblogs.com/lidabo/archive/2012/08/24/2654148.html 在参考文献基础上.补充和完善了. Matlab与C/C++混合编程接口及应用 ...

最新文章

  1. 使用容器和数据库克隆进行数据库迁移
  2. python学习--函数例子
  3. EventBus3.0 List事件遇到的坑
  4. python将dataframe写入csv_Pandas dataframe数据写入文件和数据库
  5. python把数字阿拉伯数字转换成中文10以内_Python实现把数字转换成中文
  6. easyui分页查询为什么会有下拉框_6个针对MySQL大数据量分页查询优化的锦囊妙计...
  7. shiro中ini配置文件
  8. 浅析VB For Each.Next语句
  9. Juniper Networks 修复开源操作系统 Junos OS 等中的多个严重漏洞
  10. 微信小程序——组件(二)
  11. 赢在微点答案专区英语_自考英语二太难?看了墨盒的单词本,保你信心满满去考试!...
  12. c语言程序输出数字图形,C语言数组应用之图形数字的输出
  13. 妈妈!我也会做植物大战僵尸啦!
  14. Java工程师胜任力素质模型,胜任力故事汇编C47│AspiringMinds:高潜力程序员的胜任力素质模型...
  15. 苹果服务器系统状态查询网址
  16. Java设计模式的作用
  17. Java kafka监控 topic的数据量count情况,每个topic的Summed Recent Offsets(总结最近的偏移量)
  18. Redis的使用场景有哪些?
  19. MySQL修改数据库编码
  20. 比较两组数据的差异用什么图更直观_扩增子图表解读7三元图:三组差异数量和关系...

热门文章

  1. java多属性的map_java集合(四)Map集合之Properties详解
  2. DL notes 05:深度学习相关的优化基础(入门级)
  3. 利用MATLAB视频函数工具箱的…
  4. mac更新系统版本后的安装包路径
  5. linux锁屏命令 TM,Linux基本命令的使用(上)
  6. [SUCCESS]前后端分离开发-入门案例 +VSCode安装
  7. win10下PHP开发环境搭建
  8. Android drawable微技巧,你所不知道的drawable的那些细节
  9. 抑郁症自测量表测试软件,抑郁自评:医用抑郁自测量表,快来测一测你的抑郁指数是多少...
  10. php 爬虫登录网站,Python爬虫模拟登录带验证码网站