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

Improve HashMap memory usage, add sorting capability #2556

Merged
merged 7 commits into from
Sep 21, 2022

Conversation

mikee47
Copy link
Contributor

@mikee47 mikee47 commented Sep 20, 2022

The HashMap class template currently stores both keys and values using double-indirection. This is necessary for object types (e.g. String) but for simple (scalar) types it is very wasteful of memory.

This PR delegates key/value storage to separate list class optimised for either scalar or pointer (class) types.
Also, the allocation algorithm has been adjusted to expand storage by 4 or 16 entries, instead of only one.

The stdc++ library has also been added so that std::map and std::vector can be used to compare memory usage.
The Wiring module in HostTests has been updated to show this.

A HashMap<MimeType, uint16_t> containing 13 items now uses 96 bytes instead of 182. std::map uses 312 bytes.
NB. enum declarations default to 32-bits, so reducing storage class for MimeType to uint8_t reduces map further to 48 bytes, whilst std::map reduces to 260 bytes.

One reason for the reduced memory usage is that HashMap uses two lists: one for keys, and a second for values, whilst std::map uses a single list of std::pair structures. These structures must be aligned so with small data types there is unused space.

Note, however, that a std::map will likely out-perform a simple HashMap for larger data sets as they use more sophisticated storage mechanisms https://en.cppreference.com/w/cpp/container/map. HashMap is much simpler, does not sort the keys and does lookups by iterating from the start of the map.

This PR also adds a basic sort() method so entries can be re-ordered, perhaps as part of post-processing or display.

Delegate key/value storage to separate list class optimised for either scalar or pointer (class) types
Expand storage by 4 or 16 entries, instead of only one
@slaff slaff added this to the 4.7.0 milestone Sep 20, 2022
@slaff
Copy link
Contributor

slaff commented Sep 21, 2022

TODO: Add methods so HashMap can be sorted by key or value

@mikee47 ping me when ready with this PR.

@mikee47
Copy link
Contributor Author

mikee47 commented Sep 21, 2022

@slaff OK, happy with this PR. Sorting isn't the fastest, but it is flexible.

@mikee47 mikee47 changed the title Make HashMap a bit smarter about memory allocation Improve HashMap memory usage, add sorting capability Sep 21, 2022
@slaff slaff merged commit 2ef58d1 into SmingHub:develop Sep 21, 2022
@mikee47 mikee47 deleted the feature/smart-hashmap branch September 21, 2022 12:10
slaff pushed a commit that referenced this pull request Sep 28, 2022
This PR follows on from #2556 to reduce memory usage and performance when Vector is used with simple (scalar) values.
Additional tests added.
@slaff slaff mentioned this pull request Nov 8, 2022
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants