ImportRow vs Скорость слияния Вопрос - PullRequest
4 голосов
/ 29 июля 2010

Для собственного назидания я решил проверить сравнительные скорости DataTable.ImportRow и DataTable.Merge.Я обнаружил, что DataTable.ImportRow был значительно медленнее, чем DataTable.Merge.В редких случаях обе функции имели одинаковое время обработки.В еще более редких случаях ImportRow был быстрее, чем Merge.

Ниже приведены мои результаты тестирования и код.

  1. Почему ImportRow медленнее, чем Merge?
  2. Что делает объединение быстрее?

alt text

    DataTable dt = new DataTable();

    dt.Columns.Add("customerId", typeof(int));
    dt.Columns.Add("username", typeof(string));

    for (int i = 0; i <= 100000; i++)
    {
        DataRow myNewRow;
        myNewRow = dt.NewRow();
        myNewRow["customerId"] = 1;
        myNewRow["username"] = "johndoe";
        dt.Rows.Add(myNewRow);
    }

    // First Duration
    DateTime startTime1 = DateTime.Now;

    DataTable dt2 = new DataTable();
    dt2 = dt.Clone();

    for (int i = 0; i < dt.Rows.Count; i++)
        dt2.ImportRow(dt.Rows[i]);

    DateTime stopTime1 = DateTime.Now;
    // End First Duration

    TimeSpan duration1 = stopTime1 - startTime1;

    // Second Duration
    DateTime startTime2 = DateTime.Now;

    DataTable dt3 = new DataTable();
    dt3 = dt.Clone();
    dt3.Merge(dt);

    DateTime stopTime2 = DateTime.Now;
    // End Second Duration

    TimeSpan duration2 = stopTime2 - startTime2;

Редактировать: Обновлен код согласно предложениям -

    DataTable dt = new DataTable();

    dt.Columns.Add("customerId", typeof(int));
    dt.Columns.Add("username", typeof(string));

    DataColumn[] key = new DataColumn[1];

    key[0] = dt.Columns[0];

    dt.PrimaryKey = key;

    for (int i = 0; i <= 100000; i++)
    {
        DataRow myNewRow;
        myNewRow = dt.NewRow();
        myNewRow["customerId"] = i;
        myNewRow["username"] = "johndoe";
        dt.Rows.Add(myNewRow);
    }

    // First Duration
    //DateTime startTime1 = DateTime.Now;

    Stopwatch sw1 = new Stopwatch();
    sw1.Start();

    DataTable dt2 = new DataTable();
    dt2 = dt.Clone();

    for (int i = 0; i < dt.Rows.Count; i++)
        dt2.ImportRow(dt.Rows[i]);

    //DateTime stopTime1 = DateTime.Now;
    sw1.Stop();
    // End First Duration

    TimeSpan duration1 = sw1.Elapsed;

    // Second Duration
    //DateTime startTime2 = DateTime.Now;
    Stopwatch sw2 = new Stopwatch();

    sw2.Start();

    DataTable dt3 = new DataTable();
    dt3 = dt.Clone();
    dt3.Merge(dt);

    sw2.Stop();
    //DateTime stopTime2 = DateTime.Now;
    // End Second Duration

    TimeSpan duration2 = sw2.Elapsed;

    label3.Text = duration1.Milliseconds.ToString();
    label4.Text = duration2.Milliseconds.ToString();

alt text

Ответы [ 2 ]

4 голосов
/ 29 июля 2010
  1. Ваши измеренные различия довольно малы, тем более что у вас разрешение всего 20 мс (DateTime). Используйте секундомер.

  2. Вы устанавливаете Id = 1 для всех записей, поэтому, похоже, у вас нет правильного первичного ключа. Это делает это очень непредставительным.

  3. Слияние должно быть быстрее, поскольку оно может быть оптимизировано для массовых действий. Учитывая это, я нахожу результаты еще более равными.

1 голос
/ 29 июля 2010

Прежде всего, прежде чем вы сделаете какие-либо конкретные результаты, я бы использовал «StopWatch» для определения времени, а не DateTime.Now. StopWatch - это гораздо более точный инструмент измерения, который дает более стабильные результаты.

В противном случае логично было бы иметь смысл, чтобы слияние могло иметь оптимизацию для добавления, поскольку оно предназначено для импорта сразу нескольких строк.

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