170 похожих чатов

Всем привет. Подскажите пожалуйста. При добавлении в мап элементов память

растёт не линейно? Я понимаю что память кусками выделяется но при добавлении нескольких элементов память растёт сотнями байт а при добавлении миллион и миллион+1 элемент уже изменени на десятки килобайт

вот код

func BenchmarkMapUint8(b *testing.B) {
for n := 0; n < b.N; n++ {
caseMapUint8 = make(map[int]uint8)
for i := 0; i < length; i++ {
caseMapUint8[i] = 1
}
}
}

1 элемент
BenchmarkMapUint8-4 8657696 133.5 ns/op 144 B/op 2 allocs/op

8 элементов
BenchmarkMapUint8-4 8657696 133.5 ns/op 144 B/op 2 allocs/op
9 элементов уже берётся новый кусок памяти
BenchmarkMapUint8-4 1431505 833.0 ns/op 320 B/op 3 allocs/op

По идее один элемент должен быть где то (144-48)/8 приблизительно 16 байт
но если делать 1000000
То

BenchmarkMapUint8-4 1 2059244014 ns/op 444518240 B/op 306589 allocs/op
Явно тут не 16 байт на элемент
А если 1000001 то один элемент добавил 24 килобайта

BenchmarkMapUint8-4 1 2049380999 ns/op 444542136 B/op 306835 allocs/op

29 ответов

24 просмотра

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

Andrey-Voronko Автор вопроса

У меня прямо встречный вопрос в стиле @onokonem : «А Вы знаете, как работает map'а под капотом?»

Andrey-Voronko Автор вопроса
🏳️ Phil Kulin
У меня прямо встречный вопрос в стиле @onokonem : ...

Приблизительно. По этому и спрашиваю. У Мапа память растёт нелинейно? Или это из за того что GC не успевает?

Andrey Voronko
Приблизительно. По этому и спрашиваю. У Мапа памят...

Вы можете его отключить и проверить. На первый взгляд, оно тут не при чём

Andrey-Voronko Автор вопроса
🏳️ Phil Kulin
Что должен успевать или не успевать gc?

Он не успевает память очистить. Это предположение. Что тест заканчивается быстрее чем жс успевает почистить память.

Andrey Voronko
Он не успевает память очистить. Это предположение....

он ее довольно быстро чистит. но можно глянуть в профайлере, конечно

Andrey Voronko
Приблизительно. По этому и спрашиваю. У Мапа памят...

Но меня больше интересует вопрос, а с чего предположение, что мапа в принципе может расти линейно? Ну т.е. что в принципе могло привести к такому выводу?

Andrey-Voronko Автор вопроса
🏳️ Phil Kulin
От чего почистить?

Я предположил что при добавлении элемента в мап он может для служебных целей выделять память. Например при расчёте хэша. А потом освобождать

Andrey-Voronko Автор вопроса
🏳️ Phil Kulin
Но меня больше интересует вопрос, а с чего предпол...

а почему должно быть не линейно? Размер элемента фиксирован. Хэш насколько я понимаю тоже. Откуда нелинейность должна взяться?

Andrey-Voronko Автор вопроса

Тесть это нормально для мапа что на миллионном элементе кажды новый элемент занимает 24 Кбайта?

Andrey-Voronko Автор вопроса

Я и так это уже сказал. Если не хотите отвечать то просто не отвечайте.

Я, кстати, с трудом могу понять, почему до 8 всё было ok. Точнее, я не понимаю откуда там 2 аллокации

Andrey Voronko
Я и так это уже сказал. Если не хотите отвечать то...

Я намекаю на то, что придётся посмотреть какой-нибудь 10-минутный ролики или текст - как устроена мапа

Andrey Voronko
Я и так это уже сказал. Если не хотите отвечать то...

Вот например: https://habr.com/ru/post/457728/ можно начать со слов "Мапа в Go — это..."

А зачем линейно? Аллокация памяти - штука дорогая.

Daniel Podolsky
он ее довольно быстро чистит. но можно глянуть в ...

Раз речь про профайлер зашла, норм в проде профайлером снимать нагрузки? Или в проде лучше его не использовать?

Забавно, кстати, @onokonem , это он при grow что-то явно почистить не успевает действительно. Хотя бенч flat или cum показывает? Если cum, то я не понимаю

Andrey-Voronko Автор вопроса
🏳️ Phil Kulin
Я, кстати, с трудом могу понять, почему до 8 всё ...

По вашей ссылке написано В исходном коде можно найти строчку: // Maximum average load of a bucket that triggers growth is 6.5. то есть, если в каждом «ведре» в среднем более 6,5 элементов, происходит увеличение массива buckets. При этом выделяется массив в 2 раза больше, а старые данные копируются в него маленькими порциями Это же память не в стеке выделяется? Если при новом добавлении элемента мап выделяем память и потом освобождает, то бенчмарк насколько я понимаю не покажет освобождение.

Andrey Voronko
По вашей ссылке написано В исходном коде можно най...

в стеке тольео то, размер чего можно при компиляции вычислить, по очевидным причинам

Andrey-Voronko Автор вопроса
Daniel Podolsky
в стеке тольео то, размер чего можно при компиляци...

Просто выше сказали что мап в стеке только выделяет память.

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта