Как оптимизировать это создание / обновление / удаление сравнений? - PullRequest
0 голосов
/ 23 января 2019

Я с EF 6.

У меня есть элемент списка токов в БД, который я получаю с помощью:

ae_alignedPartners_olds = ctx.AE_AlignedPartners.AsNoTracking().ToList(); // list of List<AE_AlignedPartners>

Чем я повторяю те же объекты изJSON, с:

ae_alignedPartners_news = GetJSONListObjects(); // list of List<AE_AlignedPartners>

Чем я делаю некоторые сравнения (чтобы увидеть, что мне нужно обновить, что мне нужно удалить, а что создать. Это текущий код:

// intersection
var IDSIntersections = (from itemNew in ae_alignedPartners_news
                        join itemOld in ae_alignedPartners_olds on itemNew.ObjectID equals itemOld.ObjectID
                        select itemNew).Select(p => p.ObjectID).ToList();

// to update
IList<AE_AlignedPartners> ae_alignedPartners_toUpdate = new List<AE_AlignedPartners>();
foreach (var item in IDSIntersections)
{
    var itemOld = ae_alignedPartners_olds.First(p => p.ObjectID == item);
    var itemNew = ae_alignedPartners_news.First(p => p.ObjectID == item);

    if (itemOld.Field1 != itemNew.Field1 ||
        itemOld.Field2 != itemNew.Field2 ||
        itemOld.Field3 != itemNew.Field3 ||
        itemOld.Field4 != itemNew.Field4 ||
        itemOld.Field5 != itemNew.Field5 ||
        itemOld.Field6 != itemNew.Field6 ||
        itemOld.Field7 != itemNew.Field7 ||
        itemOld.Field8 != itemNew.Field8 ||
        itemOld.Field9 != itemNew.Field9)
    {
        itemOld.Field1 = itemNew.Field1;
        itemOld.Field2 = itemNew.Field2;
        itemOld.Field3 = itemNew.Field3;
        itemOld.Field4 = itemNew.Field4;
        itemOld.Field5 = itemNew.Field5;
        itemOld.Field6 = itemNew.Field6;
        itemOld.Field7 = itemNew.Field7;
        itemOld.Field8 = itemNew.Field8;
        itemOld.Field9 = itemNew.Field9;

        ae_alignedPartners_toUpdate.Add(itemOld);
    }
}

// to create
IList<AE_AlignedPartners> ae_alignedPartners_toCreate = ae_alignedPartners_news.Where(p => !IDSIntersections.Contains(p.ObjectID)).ToList();

// to delete
IList<AE_AlignedPartners> ae_alignedPartners_toDelete = ae_alignedPartners_olds.Where(p => !IDSIntersections.Contains(p.ObjectID)).ToList();

Что достаточно быстрее для 1000 записей? За 50 тыс. Он становится очень-очень медленным.

Что вы предлагаете улучшить в целом?

1 Ответ

0 голосов
/ 23 января 2019

Если вы хотите узнать, что медленно, я предлагаю профилирование или просто 10 раз приостановить отладчик, чтобы увидеть, где он останавливается чаще всего (вы можете попробовать это с вашим существующим кодом).Но здесь я мог сразу определить проблему:

var itemOld = ae_alignedPartners_olds.First(p => p.ObjectID == item);
var itemNew = ae_alignedPartners_news.First(p => p.ObjectID == item);

Это сканирование всего списка, который является O (N).Вместе с внешним циклом это становится O (N ^ 2).

Лучшее решение было бы реструктурировать ваш запрос так, чтобы эти поиски не были необходимы.Мне кажется, что объединение уже выводит нужные вам объекты.

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

var dict_ae_alignedPartners_olds = ae_alignedPartners_olds.ToDictionary(p => p.ObjectID);
var dict_ae_alignedPartners_news = ae_alignedPartners_news.ToDictionary(p => p.ObjectID);

foreach (var item in IDSIntersections)
{
    var itemOld = dict_ae_alignedPartners_olds[item];
    var itemNew = dict_ae_alignedPartners_news[item];
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...