企業(yè)定制軟件之C#與C++混合編程及性能分析
發(fā)布時(shí)間:Mar 01, 2022
已有 人瀏覽
C#與C++混合編程及性能分析
概要:
眾所周知, ?C#做界??C++開發(fā)效率要?得多, 但在有性能問題的情況下不得不將部分模塊使?C++, 這時(shí)就需要使?C#與C++混合
編程。 本?給出了兩種混合編程的?法以及性能對(duì)?。
開發(fā)環(huán)境:
ThinkPad T430 i5-3230M 2.6G 8G, Win7 64Bit, VS2013(C++開發(fā)設(shè)置) , C++, C#都采?x64平臺(tái), 性能驗(yàn)證使?Release版本。
測(cè)試純C++項(xiàng)?性能:
1. 新建空解決?案: ?件|新建|項(xiàng)?|已安裝|模板|其他項(xiàng)?類型|Visual Studio解決?案|空?解決?案
2. 新建PureCpp項(xiàng)?: 右擊解決?案|添加|新建項(xiàng)?|已安裝|Visual C++|Win32控制臺(tái)程序, 按缺省設(shè)置?成項(xiàng)?
3. 在配置管理器中新建x64平臺(tái), 刪除其他平臺(tái)
4. 新建CppFunction, 并添加測(cè)試代碼, 完整代碼如下, 程序結(jié)果: 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 : 定義控制臺(tái)應(yīng)?程序的??點(diǎn)。
//
#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
測(cè)試純Csharp項(xiàng)?性能:
1. 新建PureCsharp項(xiàng)?: 右擊解決?案|添加|新建項(xiàng)?|已安裝|其他語?|Visual C#|控制臺(tái)應(yīng)?程序, 按缺省設(shè)置?成項(xiàng)?
2. 在配置管理器中新建x64平臺(tái), 刪除其他平臺(tái), 去掉【創(chuàng)建新的解決?案平臺(tái)】 勾選, 否則會(huì)報(bào)x64平臺(tái)已經(jīng)存在
3. 將C++項(xiàng)?中的代碼復(fù)制過來稍作改動(dòng), 完整代碼如下, 程序結(jié)果: 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
性能分析:
從上?的對(duì)?可以看出, 同樣的功能, C#的耗時(shí)?乎是C++的7倍, 這個(gè)例??的主要原因是, C++可以使??效的棧內(nèi)存對(duì)象
(CCalc) , ?C#所有對(duì)象只能放在托管堆中。
托管C++混合?式:
1. 新建C#控制臺(tái)項(xiàng)?, 命名為BenchCsharp, 使?它來調(diào)?C++項(xiàng)?, 修改?成?錄為: ..\x64\Release\
2. 新建C++DLL項(xiàng)?, 命名為DLLCpp, 選擇空項(xiàng)?, ?成成功, 但由于是空項(xiàng)?, 不會(huì)真正?成dll?件
3. 在DLLCpp為空項(xiàng)?時(shí), 在BenchCsharp中可以成功添加引?, 但當(dāng)DLLCpp中添加類后, 就不能成功添加引?了, 已經(jīng)添加的引?
也會(huì)顯?警告
4. 修改DLLCpp項(xiàng)?屬性, 右擊項(xiàng)?|屬性|配置屬性|常規(guī)|公共語?運(yùn)?時(shí)?持, 修改后就可以成功引?了
5. 在DLLCpp中添加CppFunction類, 并復(fù)制代碼, 完整代碼如下, 程序結(jié)果: 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++項(xiàng)?, 還是差了很多
將C#主函數(shù)中的邏輯轉(zhuǎn)移到DLLCpp項(xiàng)?中, 即添加如下的static?法, C#中只要調(diào)?該?法, 程序結(jié)果: 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
并沒有變得更快, 估計(jì)是當(dāng)使?【公共語?運(yùn)?時(shí)?持】 ?式編譯C++時(shí), 不能發(fā)揮C++的性能優(yōu)勢(shì)
DLLImport混合?式:
1. 新建?空的C++DLL項(xiàng)?, 命名為NativeDLLCpp
2. 將CppFunction類從PureCpp中復(fù)制過來
3. 代碼如下, 運(yùn)?結(jié)果: Result: 1733793664 Elapsed: 125
// NativeDLLCpp.cpp : 定義 DLL 應(yīng)?程序的導(dǎo)出函數(shù)。
//
#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++項(xiàng)?性能?乎?致。
項(xiàng)?依賴項(xiàng)需要?動(dòng)設(shè)置。
實(shí)現(xiàn)聯(lián)調(diào)的?法: 修改C#項(xiàng)?屬性|調(diào)試|啟?本機(jī)代碼調(diào)試