Поиск по фрагменту с очень большим количеством элементов - PullRequest
1 голос
/ 31 января 2020

Некоторое время назад я работал над API, чтобы хранить записи, хранящиеся в двух разных системах, синхронно c друг с другом. Он работал нормально, но столкнулся с проблемой с новой таблицей, которую я привожу в syn c, которая имеет большое количество записей. Ниже находится базовое c помещение.

table1 и table2 - это фрагмент структур, отражающих данные, которые я пытаюсь сохранить в синхронизации c. Это прекрасно работает около 20 000 записей. Но сейчас я работаю с 200 000, и это не очень эффективно, так как я эффективно пробегаю по каждой строке потенциально 200 000 раз, что приводит к миллиардам циклов. Есть ли более эффективный способ go сделать это?

for _, item1 = range table1 {
    for _, item2 = range table2 {
        if item1.id == item2.id {
            itemsAreEqual = reflect.DeepEqual(item1, item2)
            if !itemsAreEqual {
               //Update Stuff
            }
        }
    }
}

1 Ответ

3 голосов
/ 31 января 2020

Если порядок элементов в таблицах не важен, вместо этого используйте две карты:

for id1, item1:=range table1 {
   if item2, ok:=table2[id1]; ok {
     ...
   }
}

Если вам нужно обновить item1 и item2 членов, может быть, лучше сделать эти карты map[idType]*Item вместо map[idType]Item.

Если порядок важен, вы можете сделать то же самое с массивом и картой:

ids:=make(map[idType]*Item)
for i,item:=range table2 {
   ids[item.id]=&table2[i]
}
for id1, item1:=range table1 {
   if item2, ok:=ids[id1]; ok {
     ...
   }
}
...