Карта delete () фактически не удаляет записи - PullRequest
1 голос
/ 20 октября 2019

После многих добавлений / удалений на карте, масштабирование по карте происходит медленнее, чем ожидалось.

Рассмотрим следующий код

package main

import (
    "fmt"
    "time"
)

func main() {
    test := make(map[int]bool)
    for i := 0; i < 1000000; i++ {
        test[i] = true
    }
    for k := range test {
        delete(test, k)
    }
    test[0] = true
    fmt.Printf("test len(): %d\n", len(test))
    now := time.Now()
    for range test {
    }
    fmt.Printf("range took %v\n", time.Since(now))
}

В моей системе зацикливание тестовой карты (который содержит 1 запись) занимает 3,5 мс. Это проблема, потому что мы выполняем подобный код в производстве, и через некоторое время у нас есть много миллионов удаленных записей на карту.

GC, похоже, не помогает, и единственное решение, которое я могу придумать, это установить всю карту на ноль, а затем переделать ее. Есть ли другие способы?

1 Ответ

2 голосов
/ 20 октября 2019

Я ожидаю, что производительность будет приблизительно масштабироваться в зависимости от максимального размера, который когда-либо имел карта, но я не ожидаю, что она будет ухудшаться с дополнительными операциями записи и удаления со временем. Есть два компонента;есть время, чтобы проверить все сегменты, которые будут масштабироваться в соответствии с размером, который когда-либо имел карта, и время, чтобы получить результаты, которые будут масштабироваться в зависимости от количества имеющихся в настоящее время записей.

Но добавление и удалениедальше это не должно меняться.

https://play.golang.org/p/Ouj-3MuZvVt

См. также https://github.com/golang/go/issues/20135, отслеживание проблемы "карты не уменьшаются после удаления".

Если вам действительно нужно перебрать очень маленькую часть карты, вы можете создать новую карту, содержащую только те элементы, которые у вас есть, но вставки / удаления не будут стоить вам времени, это максимальный размер карты;обратите внимание, насколько меньше время, если вы добавляете и удаляете 1000 элементов 1000 раз, а не добавляете миллион элементов, а затем удаляете их.

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