在这一部分,我们将用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<< 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 << L?DELETE WHERE Usage:\tdb2 [rows]?); return; NUM="int.Parse(args[0]);" OleDbConnection connection; connection="new" OleDbConnection( ?Provider='Microsoft.Jet.OLEDB.4.0;"' ?Data Source='c:\\db.mdb;");' connection.Open(); ss.Append(?INSERT col2)? VALUES (?); ss.Append(?, ?????); ss.Append(i+1); ss.Append(?????)?); ss.ToString(), command.ExecuteNonQuery(); long j="0;j<100;j++)" DataSet dataset="new" DataSet(); OleDbCommand command="new" OleDbCommand( ?SELECT col1, col2 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}",' dt="DateTime.Now.Ticks;" for (int i="0;i < pre> 下表为运行十次,每次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 <msxml3.dll> named_guids #include <iostream> int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage:\txml [filename]\n"; return 1; }; ::CoInitialize(NULL); DWORD dw = ::GetTickCount(); for (int i=0;i<100;i++) { MSXML2::IXMLDOMDocumentPtr DomDocument( MSXML2::CLSID_DOMDocument) ; _bstr_t filename = argv[1]; DomDocument->async = false; DomDocument->load(filename); } DWORD dw2 = ::GetTickCount(); std::cout << "Milliseconds = " << dw2-dw << 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<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所拥有的丰富内涵来说,用以上四个方面的测试以及简陋的文章来说明它的快或者慢是远远不够的。