简体   繁体   中英

Difference between two instances of HashMap<String, String> and an instance of HashMap<String,Object> where Object contains the two Strings

For simplicity's sake, let's say I have two instances of HashMap<String, String> where they share the same keys. What I want to know is there a performance and memory difference between that and representing those two String values in an Object and storing them in HashMap<String, Object> .

My actual problem uses an instance of HashMap<String, HashSet<String>> and two instances of HashMap<String, Double> and I was hoping that by consolidating them, I'd save memory somehow, but I wasn't sure if there'd be a performance impact from using self-defined Object versus a native object like HashSet or Double as values.

The hashes are calculated from the strings, so there won't be a speed impact. The space impact (a very slight increase) will be negligible in the long run. If it makes the code more legible, do it and screw the performance (as long as we're not talking huge performance bottlenecks, it doesn't matter).

Speed

For the speed impact, remember that in a HashMap<String, ?> , the String is what gets hashed. You may see a small increase in speed, actually, since you'll only have to do one lookup to find your custom object compared to 3 lookups.

Space

For space impact, remember that HashMap uses an inner array that's the size of a power of 2. If you're using just a vanilla HashMap with no special settings like a custom load factor, then you may see a slight space increase because right now you have (roughly, of course, this is just simplified):

HashSet<String>[]
Double[]
Double[]

And after combining it, you'll have

CustomObject[]
    HashSet<String>
    Double
    Double

This is ignoring constant-size information that doesn't grow with the map. Objects take up more space than just the references to their fields, but not very much.

Legibility

The custom object option wins this one hands-down. It's way cleaner and is very OOP, fitting into Java very, very well. Regardless of the performance, you should do this anyway. It'll look better in the long run and be more maintainable.

For example, if you wanted to add fields to the custom object, that's easy. But having the separate maps means creating more maps for more variables, which is dirty. I say go the OOP way.

If you want to combine them, create a class to represent them and have a map of those:

public class Stuff {
    String a;
    String b;
    // other fields - maybe the double you mentioned
}

HashMap<String, MyStuff> map;

That will definitely save memory because you'll have less map entries.

However, it's the right way to do it anyway. Design time is not the time to worry about tiny performance and memory impacts. Make your code easy to read and use and your life (and code) will ne better.

Unless you are dealing with a very large number of entries, the difference (if any) is likely to be unimportant. It will also be intimately tied to the platform (JVM version, Java library version, etc) and so your only useful answer will come from a profiler run against each different way of doing it.

You might consider looking at the Guava Multimap . It might be a cleaner solution to your problem. Failing that, I would use the custom object. Code clarity wins against premature optimization every time.

You're probably better off in many ways by combining the tables. Speedwise, you only have to compute the hash and walk the hash chains once instead of twice. For space, you need only one hash table instead of two (saving about 8 bytes per entry if your load factor is around 50%) and one hash chain instead of two (saving a hash chain object at about 16 bytes per entry). You pay the cost of your pair object, but that's at most 16 bytes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM