If your map has a pointer type on both sides the cost of a map lookup is basically a deference (a few cycles), and the memory usage is the size of a system int (int32 for x86, int64 for x86_64) for each key:value pair.
This makes large maps fast, and low memory usage.
Synchronizing access to a map will be slower. You can wrap the map in a type that provides a simple get/put interface which can hide synchronization details (for example, you could shard the map to reduce mutex contention and hide this in the impl…)