荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: bigone (好好学习), 信区: Visual
标  题: C#和C++的速度大比拼(第二部分)
发信站: 荔园晨风BBS站 (Sat Jul 12 12:28:43 2003), 站内信件



  在这一部分,我们将用C++和C#代码来测试两者对数据库的存取和处理。方法
是对同一个数据库表进行操作。表结构如下: CREATE TABLE testtable
(
col1 INTEGER,
col2 VARCHAR(50),

PRIMARY KEY (col1)
)

  测试将分三个部分,第一部分和第三部分集中对数据处理,第二部分集中对数
据存取。数据处理和数据存取的测试结果是分开呈现的。 下面是数据存取和处理
的C++代码: 代码五:db.cpp
#import "msado15.dll" \
no_namespace rename("EOF", "EndOfFile")
#include <iostream>
#include <string>
#include <sstream>

int main(int argc, char* argv[])
{
if (argc != 2)
{
std::cerr << "Usage:\tdb [rows]\n";
return 1;
};

::CoInitialize(NULL);
int NUM = atoi(argv[1]);
DWORD dw = ::GetTickCount();
_ConnectionPtr conptr(__uuidof(Connection));
conptr->Open(L"Provider=Microsoft.Jet.OLEDB.4.0;"
"Data Source=c:\\db.mdb;",
L"",
L"",
adOpenUnspecified);
for (int i=0;i<NUM;i++)
{
VARIANT RecordsEffected;
RecordsEffected.vt = VT_INT;
std::wstringstream ss;
ss << L"INSERT INTO testtable (col1, col2) "
<< "VALUES ("
<< i+1 << L", ''" << i+1 << L"'')";
_bstr_t sql = ss.str().c_str();
conptr->Execute(sql, &RecordsEffected, adCmdText);
};

DWORD dw2 = ::GetTickCount();
std::cout << "Milliseconds = " << dw2-dw
<< std::endl;
dw = ::GetTickCount();
for (int j=0;j<100;j++)
{
_RecordsetPtr rsptr(__uuidof(Recordset));
rsptr->Open(L"SELECT col1, col2 FROM testtable",
conptr.GetInterfacePtr(),
adOpenForwardOnly, adLockOptimistic, adCmdText);
while (rsptr->EndOfFile)
{
_variant_t v1 = rsptr->GetCollect("col1");
_variant_t v2 = rsptr->GetCollect("col2");
rsptr->MoveNext();
};
rsptr->Close();
};

dw2 = ::GetTickCount();
std::cout << "Milliseconds = " << dw2-dw
<< std::endl;
dw = ::GetTickCount();
for (int i=0;i<NUM;i++)
{
std::wstringstream ss;
VARIANT RecordsEffected;
RecordsEffected.vt = VT_INT;
ss << L"DELETE FROM testtable WHERE col1 = "
<< i+1;
_bstr_t sql = ss.str().c_str();
conptr->Execute(sql, &RecordsEffected, adCmdText);
};
conptr->Close();
dw2 = ::GetTickCount();
std::cout << "Milliseconds = " << dw2-dw
<< std::endl;
::CoUninitialize();
return 0;
}
  下面是数据存取和处理的C#代码: 代码六:db2.cs
using System;
using System.Data;
using System.Data.OleDb;
using System.Text;

namespace Db
{
class Class1
{
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.WriteLine("Usage:\tdb2 [rows]");
return;
}

int NUM = int.Parse(args[0]);
long dt = DateTime.Now.Ticks;
OleDbConnection connection;
connection = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;"
"Data Source=c:\\db.mdb;");
connection.Open();
for (int i=0;i<NUM;i++)
{
StringBuilder ss = new StringBuilder();
ss.Append("INSERT INTO testtable (col1, col2)"
" VALUES (");
ss.Append(i+1);
ss.Append(", ''");
ss.Append(i+1);
ss.Append("'')");

OleDbCommand command = new OleDbCommand(
ss.ToString(), connection);
command.ExecuteNonQuery();
};

long dt2 = DateTime.Now.Ticks;
System.Console.WriteLine("Milliseconds = {0}",
(dt2-dt)/10000);
dt = DateTime.Now.Ticks;
for (int j=0;j<100;j++)
{
DataSet dataset = new DataSet();
OleDbCommand command = new OleDbCommand(
"SELECT col1, col2 FROM testtable",
connection);
OleDbDataReader reader =
command.ExecuteReader();
while (reader.Read() == true)
{
int v1 = reader.GetInt32(0);
string v2 = reader.GetString(1);
};
reader.Close();
};

dt2 = DateTime.Now.Ticks;
System.Console.WriteLine("Milliseconds = {0}",
(dt2-dt)/10000);
dt = DateTime.Now.Ticks;
for (int i=0;i<NUM;i++)
{
StringBuilder ss = new StringBuilder();
ss.Append("DELETE FROM testtable "
"WHERE col1 = ");
ss.Append(i+1);
OleDbCommand command = new OleDbCommand(
ss.ToString(), connection);
command.ExecuteNonQuery();
};

connection.Close();
dt2 = DateTime.Now.Ticks;
System.Console.WriteLine("Milliseconds = {0}",
(dt2-dt)/10000);
}
}
}
  下表为运行十次,每次100行记录的结果 表三:数据库测试结果
序号
C++(~毫秒)
C#(~毫秒)

1 1612/441/450 4086/630/560
2 391/410/441 490/630/520
3 370/421/440 480/510/440
4 371/420/451 470/510/450
5 370/421/461 460/500/450
6 371/420/461 470/500/460
7 370/411/471 470/500/460
8 381/410/451 460/510/470
9 370/421/450 470/510/470
10 391/410/461 460/510/470
平均值 499/419/454 832/531/475

  这个结果让人十分惊讶。.NET在这里的表现是令人满意的。一般来说下降百分
之二十五的性能是可以忍受的。这说明.NET在这里是赢家。

XML性能测试
  XML是数据处理领域的最新技术。许多人对用C#代码和Visaul C++代码处理或
解析XML文件的性能很感兴趣。
下面是一段存取和处理XML的C++代码:
代码七:xml.cpp
#import &tl;msxml3.dll&gl; named_guids
#include &tl;iostream&gl;
int main(int argc, char* argv[])
{
if (argc != 2)
{
std::cerr &tl;&tl; "Usage:\txml [filename]\n";
return 1;
};

::CoInitialize(NULL);
DWORD dw = ::GetTickCount();
for (int i=0;i&tl;100;i++)
{
MSXML2::IXMLDOMDocumentPtr DomDocument(
MSXML2::CLSID_DOMDocument) ;
_bstr_t filename = argv[1];
DomDocument-&gl;async = false;
DomDocument-&gl;load(filename);
}

DWORD dw2 = ::GetTickCount();
std::cout &tl;&tl; "Milliseconds = " &tl;&tl; dw2-dw
&tl;&tl; std::endl;
::CoUninitialize();
return 0;
}

下面是一段存取和处理XML的C#代码: 代码七:xml.cs
using System;
using System.Xml;

namespace xml2
{
class Class1
{
static void Main(string[] args)
{
if (args.Length != 1)
{
Console.WriteLine("Usage:\txml [filename]");
return;
}

long dt = DateTime.Now.Ticks;
for (int i=0;i&tl;100;i++)
{
XmlDocument doc = new XmlDocument();
doc.Load(args[0]);
}

long dt2 = DateTime.Now.Ticks;
System.Console.WriteLine("Milliseconds = {0}", (dt2-dt)/10000);
}
}
}
  运行十次的结果如下:
表四:XML 测试结果
序号 C++(~毫秒) C#(~毫秒)
1 241 1111
2 170 841
3 161 841
4 170 861
5 160 861
6 171 851
7 170 841
8 160 831
9 160 841
10 170 851
平均值 203 873

  这个结果又让人惊讶一次。很难相信.NET XML类的运行效率比同等的ActiveX
类要慢四至五倍。为什么会发生这种情况呢?也许只有微软的兄弟才知道。也许微
软想要把.NET类设计成在某一方面与众不同。如果不是这样,那么微软的那帮家伙
应该好好优化一下他们的.NET XML类。
如果你是一个Web 服务和服务器应用的开发人员,当把.NET框架用于需要很高性能
的应用时,尤其是XML服务时,应三思而行。

总结
  需要强调的一点是.NET框架还是一种新的技术。因此,在这个框架中需要做的
事情还有很多,它还需要不断优化。另外,这里对.NET的性能测试也很肤浅,以.
NET所拥有的丰富内涵来说,用以上四个方面的测试以及简陋的文章来说明它的快
或者慢是远远不够的。(全文完)


--
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.1.49]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店