多次循环访问DataTable

时间:2012-02-07 08:22:42

标签: c# loops datatable

在C#(.NET 3.5)中,我使用数据库中的行填充了DataTable。在这个DataTable中,大约有100到200个DataRows。我必须遍历此DataTable以检查数据是否正确并且我使用了27种检查方法。首先,我试图将DataTable传递给每个方法并循环它。在我的第二次尝试中,我循环了DataTable一次并将DataRow传递给每个方法。之后我对这两种方法进行了基准测试,第一种方法比第二种方法更快?

将DataTable循环27次需要13秒。

循环使用DataTable 1次需要18秒。

那么对此有何解释?什么是循环使用DataTable检查数据的最快方法?

注意:基准测试是在我开始检查方法之前启动的,以排除与数据库的连接速度。

第一种方法:

private void check()
{
    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
    sw.Start();

    checkStamnr();
    checkVoornaam();
    checkGebDatum();
    ...

    sw.Stop();
    sw.Reset();
}

private void checkStamnr()
{
    foreach (DataRow dr in dtIdentificatieRecords.Rows)
    {
        if (dr["STAMNRVOL"] == null || dr["STAMNRVOL"].GetType() == typeof(DBNull) || dr["STAMNRVOL"].equals(""))
        {
            DatabankFout df = new DatabankFout("Stamnummer is leeg.");
            listDBFouten.Add(df);
        }
    }
}

第二种方法

private void check()
{
    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
    sw.Start();

    foreach (DataRow dr in dtIdentificatieRecords.Rows)
    {
        checkStamnr(dr);
        checkVoornaam(dr);
        checkGebDatum(dr);
        ...
    }

    sw.Stop();
    sw.Reset();
}

private void checkStamnr(DataRow dr)
{
    if (dr["STAMNRVOL"] == null || dr["STAMNRVOL"].GetType() == typeof(DBNull) || dr["STAMNRVOL"].equals(""))
    {
        DatabankFout df = new DatabankFout("Stamnummer is leeg.");
        listDBFouten.Add(df);
    }
}
根据要求

Class DatabankFout:

public class DatabankFout
{
    public DatabankFout(string reden, bool rood)
    {
        this.reden = reden;
        this.rood = rood;
    }
    public DatabankFout(string reden) : this(reden, false)
    {
    }

    public string reden { get; set; }
    public bool rood { get; set; }
}

2 个答案:

答案 0 :(得分:1)

我想说,一次运行中只有25%的运行时间差异并不重要。 对列表中的10000个项目至少运行10次测试。 如果第一个仍然更快,我将有一些想法。

主要部分时间可能来自创建DatabankFout,它可能是数据库连接。

答案 1 :(得分:1)

对我来说似乎不可能。我在我的机器上进行了测试。你的第一个多循环方法比一个循环方法运行得慢得多。

enter image description here

请查看我附带的控制台演示。

class Program
{
    DataTable dtIdentificatieRecords = GetTable();

    String checkTimeSpan, check2TimeSpan;
    static void Main(string[] args)
    {
        Program Test = new Program();
        Test.check();
        Test.check2();

        Console.WriteLine("checkTimeSpan: {0}", Test.checkTimeSpan);

        Console.WriteLine("check2TimeSpan: {0}", Test.check2TimeSpan);

        Console.ReadLine();
    }

    /// <summary>
    /// This example method generates a DataTable.
    /// </summary>
    static DataTable GetTable()
    {
        //
        // Here we create a DataTable with four columns.
        //
        DataTable table = new DataTable();
        table.Columns.Add("STAMNRVOL", typeof(string));
        table.Columns.Add("Drug", typeof(string));
        table.Columns.Add("Patient", typeof(string));
        table.Columns.Add("Date", typeof(DateTime));

        //
        // Here we add five DataRows.
        //
        for (int a = 0; a < 999999; a++)
        {
            table.Rows.Add(a%2==0?a.ToString():"", "Indocin", "David", DateTime.Now);
        }
        return table;
    }

    private void check()
    {
        Stopwatch stopwatch = new Stopwatch();

        stopwatch.Start();

        checkStamnr();
        checkStamnr();
        checkStamnr();
        checkStamnr();
        checkStamnr();

        stopwatch.Stop();

        checkTimeSpan = stopwatch.Elapsed.TotalSeconds.ToString();

        stopwatch.Reset();
    }

    private void checkStamnr()
    {
        foreach (DataRow dr in dtIdentificatieRecords.Rows)
        {
            if (dr["STAMNRVOL"] == null || dr["STAMNRVOL"].GetType() == typeof(DBNull) || dr["STAMNRVOL"].Equals(""))
            {
                DatabankFout df = new DatabankFout("Stamnummer is leeg.");
            }
        }
    }

    private void check2()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();

        foreach (DataRow dr2 in dtIdentificatieRecords.Rows)
        {
            checkStamnr2(dr2);
            checkStamnr2(dr2);
            checkStamnr2(dr2);
            checkStamnr2(dr2);
            checkStamnr2(dr2);

        }

        sw.Stop();

        check2TimeSpan = sw.Elapsed.TotalSeconds.ToString();

        sw.Reset();
    }

    private void checkStamnr2(DataRow dr)
    {
        if (dr["STAMNRVOL"] == null || dr["STAMNRVOL"].GetType() == typeof(DBNull) || dr["STAMNRVOL"].Equals(""))
        {
            DatabankFout df = new DatabankFout("Stamnummer is leeg.");

        }
    }

}

public class DatabankFout
{
    public DatabankFout(string reden, bool rood)
    {
        this.reden = reden;
        this.rood = rood;
    }
    public DatabankFout(string reden)
        : this(reden, false)
    {
    }

    public string reden { get; set; }
    public bool rood { get; set; }
}