Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: language: allow getting capacity of map? #52157

Closed
bradfitz opened this issue Apr 5, 2022 · 10 comments
Closed

proposal: language: allow getting capacity of map? #52157

bradfitz opened this issue Apr 5, 2022 · 10 comments

Comments

@bradfitz
Copy link
Contributor

bradfitz commented Apr 5, 2022

I posted a quiz on Twitter:

func main() {
	m := make(map[int]int, 500)
	fmt.Println(len(m))
	fmt.Println(cap(m))
}

Only 21% of people got it right, that it fails to compile with:

invalid argument: m (variable of type map[int]int) for cap

It's a little weird that you can kinda set the capacity of a map (a hint) but you can't get it back out. (Where "it" is really an "optional capacity hint")

I imagine the reason is the same reason that the previous proposal to automatically round up slice capacities to the nearest slab class was declined: it binds us to an implementation, or at least leaks their details that we'd be locked into.

Filing a bug in any case, as I can't find any past discussions of it on the issue tracker, and don't remember hearing any discussions elsewhere.

My motivation, FWIW, was to periodically re-make a map representing a set of work to do when it dropped back down to len(m) == 0. But I only wanted to re-make it if the underlying hash map capacity had grown enough to be worthwhile. Of course that's all just a workaround for #20135 (maps not shrinking). And that means I wanted more than just the initial capacity hint; I wanted to see the underlying capacity change as a function of insertions into the map.

@randall77
Copy link
Contributor

I think I'd rather just make maps shrinkable.

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Apr 5, 2022
@beoran
Copy link

beoran commented Apr 6, 2022

I think both cases would be useful. Allowing cap() on maps would make Go more consistent and easier to learn, even if it is only informative.

And making maps shrink automatically is also a useful feature but that is what issue #20135 is for.

@rsc
Copy link
Contributor

rsc commented Apr 13, 2022

It's hard to explain what cap means at all. It's a rough estimate of the size of the underlying storage and that's about it.
Unlike cap on slices and chans, it is not a guarantee about being able to store that much without resizing / blocking.

@rsc
Copy link
Contributor

rsc commented Apr 13, 2022

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc rsc moved this from Incoming to Active in Proposals (old) Apr 13, 2022
@rsc
Copy link
Contributor

rsc commented May 4, 2022

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@rsc rsc moved this from Active to Likely Decline in Proposals (old) May 4, 2022
@rsc rsc moved this from Likely Decline to Declined in Proposals (old) May 11, 2022
@rsc
Copy link
Contributor

rsc commented May 11, 2022

No change in consensus, so declined.
— rsc for the proposal review group

@AndrewWPhillips
Copy link

I couldn't find the discussion that Russ mentioned (but I think I know the gist). I still think this is a worthwhile idea. An alternative would be to add a builtin function as part of the unsafe "package".

@ianlancetaylor
Copy link
Contributor

@AndrewWPhillips Sorry, this proposal is closed. We aren't going to reopen it without new information that we didn't previously consider.

@deltics
Copy link

deltics commented Feb 20, 2024

I don't know if this meets the threshold for "new information" sufficient to reopen the issue, but I've just run into this in the following scenario....

Developing a module which internally uses a map in a struct type that is initialised using a func where the caller indicates a desired capacity for the contained map. Without the ability to determine the capacity of the newly initialised map, it is not possible to write a unit test to verify that the initialisation function returned a correctly initialised struct.

For all other types where make() supports establishing an initial capacity, cap() is available to determine the capacity. A map being the only exception is perplexing and frustrating but, more seriously and significantly, is an impediment to testing.

I cannot conceive of any problem that addressing this omission/exception would create and would appreciate consideration being given to re-opening the proposal.

@Relect
Copy link

Relect commented Apr 25, 2024

Я не знаю, соответствует ли это порогу «новой информации», достаточному для повторного открытия проблемы, но я только что столкнулся с этим в следующем сценарии....

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

Для ** всех ** остальных типов, где make()поддерживает создание первоначальной мощности, cap()доступен для определения емкости. А mapбудучи единственным исключением, это сбивает с толку и разочаровывает, но, что более серьезно и важно, это является препятствием для тестирования.

Я не могу себе представить какую-либо проблему, которую могло бы создать устранение этого упущения/исключения, и был бы признателен за рассмотрение возможности повторного рассмотрения предложения.

I uphold

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

No branches or pull requests

9 participants