南京软件定制开发

南京倾心软件欢迎您访问本站

13605185909

新闻资讯

NEWS CENTER
栏目导航

企业定制软件之C#与C++混合编程及性能分析

发布时间:Mar 01, 2022         已有 人浏览
C#C++混合编程及性能分析
概要:
众所周知, ⽤
C#做界⾯⽐C++开发效率要⾼得多, 但在有性能问题的情况下不得不将部分模块使⽤C++, 这时就需要使⽤C#C++混合
编程。 本⽂给出了两种混合编程的⽅法以及性能对⽐。
开发环境:

ThinkPad T430 i5-3230M 2.6G 8GWin7 64BitVS2013C++开发设置) , C++C#都采⽤x64平台, 性能验证使⽤Release版本。
测试纯
C++项⽬性能:
1. 新建空解决⽅案: ⽂件|新建|项⽬|已安装|模板|其他项⽬类型|Visual Studio解决⽅案|空⽩解决⽅案
2. 新建PureCpp项⽬: 右击解决⽅案|添加|新建项⽬|已安装|Visual C++|Win32控制台程序, 按缺省设置⽣成项⽬
3. 在配置管理器中新建x64平台, 删除其他平台
4. 新建CppFunction, 并添加测试代码, 完整代码如下, 程序结果: Result: 1733793664 Elapsed: 109
// CppFunction.h
#pragma once
class CppFunction
{
p
ublic
:
CppFunction(){}
~CppFunction(){}

int TestFunc(int a, int b);
};

// CppFunction.cpp
#include "stdafx.h"
#include "CppFunction.h"
class CCalc
{
p
ublic
:
CCalc(
int a, int b)
{
m_a = a;
m_b = b;
}
i
nt
Calc()
{

if (m_a % 2 == 0){
return m_a + m_b;
}
if
(m_b % 2 == 0){
return m_a - m_b;
}
r
eturn
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);
}
}D
WORD end = ::GetTickCount();
cout <<
"Result: " << result << " Elapsed: " << end - start << endl;
return 0;
}
V
iew Code

测试纯Csharp项⽬性能:
1. 新建PureCsharp项⽬: 右击解决⽅案|添加|新建项⽬|已安装|其他语⾔|Visual C#|控制台应⽤程序, 按缺省设置⽣成项⽬
2. 在配置管理器中新建x64平台, 删除其他平台, 去掉【创建新的解决⽅案平台】 勾选, 否则会报x64平台已经存在
3. C++项⽬中的代码复制过来稍作改动, 完整代码如下, 程序结果: Result: 1733793664 Elapsed: 729
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;
}
p
ublic int
Calc()
{

if (m_a % 2 == 0)
{

return m_a + m_b;
}
if
(m_b % 2 == 0)
{

return m_a - m_b;
}
r
eturn
m_b - m_a;
}
p
rivate int
m_a;
private int m_b;
}
c
lass
CppFunction
{

public int TestFunc(int a, int b)
{
CCalc calc =
new CCalc(a, b);
return calc.Calc();
}
}
c
lass
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);
}
}D
ateTime end = System.DateTime.Now;

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

性能分析:
从上⾯的对⽐可以看出, 同样的功能,
C#的耗时⼏乎是C++7倍, 这个例⼦⾥的主要原因是, C++可以使⽤⾼效的栈内存对象
CCalc) , ⽽C#所有对象只能放在托管堆中。
托管
C++混合⽅式:
1. 新建C#控制台项⽬, 命名为BenchCsharp, 使⽤它来调⽤C++项⽬, 修改⽣成⽬录为: ..\x64\Release\
2.
新建C++DLL项⽬, 命名为DLLCpp, 选择空项⽬, ⽣成成功, 但由于是空项⽬, 不会真正⽣成dll⽂件
3. DLLCpp为空项⽬时, 在BenchCsharp中可以成功添加引⽤, 但当DLLCpp中添加类后, 就不能成功添加引⽤了, 已经添加的引⽤
也会显⽰警告

4. 修改DLLCpp项⽬属性, 右击项⽬|属性|配置属性|常规|公共语⾔运⾏时⽀持, 修改后就可以成功引⽤了
5. DLLCpp中添加CppFunction类, 并复制代码, 完整代码如下, 程序结果: Result: 1733793664 Elapsed: 405
// CppFunction.h
#pragma once
public ref class CppFunction
{
p
ublic
:
CppFunction(){}
~CppFunction(){}

int TestFunc(int a, int b);
};

// CppFunction.cpp
#include "CppFunction.h"
class CCalc
{
p
ublic
:
CCalc(
int a, int b)
{
m_a = a;
m_b = b;
}
i
nt
Calc()
{

if (m_a % 2 == 0){
return m_a + m_b;
}
if
(m_b % 2 == 0){
return m_a - m_b;
}
r
eturn
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();
}
V
iew Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BenchCsharp
{

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);
}
}D
ateTime end = System.DateTime.Now;
System.Console.WriteLine(
"Result: " + result + " Elapsed: " + (end - start).Milliseconds);
}
}
}
V
iew Code

性能分析:
使⽤混合编程后, 性能得到了⼀定程度的提升, 但⽐起单纯的
C++项⽬, 还是差了很多
C#主函数中的逻辑转移到DLLCpp项⽬中, 即添加如下的static⽅法, C#中只要调⽤该⽅法, 程序结果: Result: 1733793664
Elapsed: 405

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);
}
}D
WORD end = ::GetTickCount();
cout <<
"Result: " << result << " Elapsed: " << end - start << endl;
return result;
}
V
iew Code

并没有变得更快, 估计是当使⽤【公共语⾔运⾏时⽀持】 ⽅式编译C++时, 不能发挥C++的性能优势
DLLImport混合⽅式:
1. 新建⾮空的C++DLL项⽬, 命名为NativeDLLCpp
2.
CppFunction类从PureCpp中复制过来
3. 代码如下, 运⾏结果: Result: 1733793664 Elapsed: 125
// 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);
}
}D
WORD end = ::GetTickCount();
cout <<
"Result: " << result << " Elapsed: " << end - start << endl;
return result;
}
V
iew Code

public class NativeDLLCpp
{
[DllImport(
"NativeDLLCpp.dll")]
public static extern int Test();
}
c
lass
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);
}
}

View Code
性能分析:
跟纯
C++项⽬性能⼏乎⼀致。
项⽬依赖项需要⼿动设置。
实现联调的⽅法: 修改
C#项⽬属性|调试|启⽤本机代码调试

Copyright © 2020-2022 南京倾心软件技术有限公司 版权所有     苏ICP备2020070309号-1
QQ在线咨询
13605185909
返回顶部