Цикл по DataTable несколько раз - PullRequest
2 голосов
/ 07 февраля 2012

В 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);
    }
}

Класс 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 ]

1 голос
/ 07 февраля 2012

Мне кажется невозможным.Я провел тест на своей машине.Ваш первый метод с несколькими циклами работает намного медленнее, чем один цикл.

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; }
}
1 голос
/ 07 февраля 2012

Я бы сказал, что разница во времени выполнения в 25% за один прогон с таким количеством элементов незначительна.Запустите тест по крайней мере 10 раз для 10000 пунктов в списке.Если первое все еще быстрее, у меня будет о чем подумать.

Основная часть времени, вероятно, исходит от создания DatabankFout, который может быть соединением с базой данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...