C# 中的 ACEDAO 性能比 VB.net 慢得多

Posted

技术标签:

【中文标题】C# 中的 ACEDAO 性能比 VB.net 慢得多【英文标题】:ACEDAO performance in C# much slower than VB.net 【发布时间】:2013-12-06 03:00:43 【问题描述】:

在 C# 项目中,我需要用大量数据填充 Access 2010 数据库,而性能是一个问题。我使用各种数据访问技术进行了一些测试,发现使用老式 DAO 可以提供最佳性能(使用我在 *** 上找到的代码示例)。下面的代码大约需要 2.5 秒来填充一个包含 100,000 条记录的 6 列表。

Dao.DBEngine eng = new Dao.DBEngine();
Dao.Database db = eng.OpenDatabase(@"d:\temp\speedtest.accdb");
eng.BeginTrans();

Dao.Recordset rs = db.OpenRecordset("tblTest");
Dao.Field[] myFields = new Dao.Field[6];
for (int k = 0; k <= 5; k++) 
    myFields[k] = rs.Fields[k];


for (int i = 1; i <= 100000; i++) 
    rs.AddNew();
    myFields[0].Value = i;
    myFields[1].Value = i;
    myFields[2].Value = i;
    myFields[3].Value = i.ToString();
    myFields[4].Value = i.ToString();
    myFields[5].Value = i.ToString();
    rs.Update();


eng.CommitTrans();

出于好奇,我在 VB.net 中逐行重写了这段代码。

Dim eng As New Dao.DBEngine()
Dim db As Dao.Database = eng.OpenDatabase("d:\temp\speedtest.accdb")
eng.BeginTrans()

Dim rs As Dao.Recordset = db.OpenRecordset("tblTest")
Dim myFields() As Dao.Field = New Dao.Field(5) 
For k As Integer = 0 To 5
    myFields(k) = rs.Fields(k)
Next

Dim startTime As DateTime = DateTime.Now
For i As Integer = 1 To 100000
    rs.AddNew()
    myFields(0).Value = i
    myFields(1).Value = i
    myFields(2).Value = i
    myFields(3).Value = i.ToString()
    myFields(4).Value = i.ToString()
    myFields(5).Value = i.ToString()
    rs.Update()
Next

eng.CommitTrans()

VB.net 版本的运行时间约为 0.26 秒,比 C# 版本快大约 10 倍。我发现这种差异令人震惊,我无法解释这一点。当我使用 Reflector 查看 IL 代码时,我看不到明显的差异。项目是相同的(两个控制台应用程序),上面的代码在 main 方法中。任何人都知道如何获得具有相同性能的 C# 版本?

【问题讨论】:

尝试先运行 VB 版本,然后再运行 C# 版本。第二个比第一个慢吗? 显然,两者都以相同的方式运行,即都没有附加调试器。 就像@KrisVandermotten 暗示的那样,它可能更多地与SQL 缓存执行计划有关。如果有的话,默认情况下 C# 会稍微快一些,因为不会检查循环中的 ints 是否溢出。 @DouglasBarbin Access 2010 并不完全是 SQL Server。但数据文件和 DLL 可能在磁盘缓存中。 @KrisVandermotten 我错过了他所说的 Access。哎呀。这些天我的脑海里自动默认使用 SQL。 【参考方案1】:

首先,感谢所有为我提供有用提示和建议的人。与 VB 对应的程序相比,我发现了 C# 程序执行如此糟糕的原因。

如果 C# 代码是作为“正常”开发解决方案的一部分编写的,我就不会遇到这个问题。但是很遗憾,当你启动一个 C# 控制台项目时,main 方法并没有获取到 [STAThread] 属性。我还没有弄清楚为什么控制台程序默认缺少此属性,但是当添加到我的示例程序中时,C# 和 VB 代码执行完全相同(给定或花费几毫秒)。

【讨论】:

以上是关于C# 中的 ACEDAO 性能比 VB.net 慢得多的主要内容,如果未能解决你的问题,请参考以下文章

Scala 性能:为啥这个 Scala 应用程序比同等的 Java 应用程序慢 30 倍?

C# 和 VB.NET 的优缺点?

如何从 C# 读取 VB.NET 项目中的“app.config”文件

需要帮助将 c# 中的 opencv 转换为 vb.net

C# 应用程序与 C++ 和 VB.Net 中的其他应用程序之间的 IPC

C#与VB.net有啥不同呀?