2012-02-07 3 views
2

В C# (.NET 3.5) Я заполнил DataTable строками из моей базы данных. В этом DataTable существует от 100 до 200 DataRows. Я должен пройти через этот DataTable, чтобы проверить правильность данных, и я использую 27 check-методов. Сначала я попытался передать DataTable каждому методу и зациклить его. Во второй попытке я зациклил DataTable один раз и передал DataRow каждому методу. Впоследствии я сравнивал эти два метода, и первый метод был быстрее второго?Цитирование через DataTable несколько раз

Looping the DataTable 27 раз занял 13 секунд.

Looping the 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

Трудно помочь без Seing кода ... –

+0

Добавлен код ;-) – Yoni

+1

Как тяжел ваш 'DatabankFout' класс и что такое' listDBFouten'? Чтобы проверить, какой метод выполняется быстрее, вы должны удалить все несвязанные, которые идентичны для обоих. Цикл 100 строк определенно не может длиться 13/18 секунд (если вы не на C64), возможно, вы использовали StopWatch и забыли остановить/сбросить во время отладки (13 миллисов более реалистично). Вместо того, чтобы передавать данные в формате wohole datatable или datarow, вы должны передавать только то, что необходимо - данные, хранящиеся в datacolumn. –

ответ

1

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

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

+0

DatabankFout имеет только свойства и не имеет никакого подключения к базе данных. – Yoni

+0

Итак, как это может занять столько времени? Мы говорим о нескольких тысячах сравнений свойств. Это можно сделать гораздо меньше, чем за 1 секунду. Имеет ли listDBFouten.Add что-то вроде сортировки или других медленных вещей? –

+0

Вы можете увидеть DatabankFout в моем открытии. Я просто попытался зацикливать DataTable 1000 раз без какого-либо check-метода, и он закончил в 7 мс. Затем я попробовал его с одним методом проверки, и он еще не закончил через одну минуту. – Yoni

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