Will the compiler generate better code if it knows the actual class it will be working with vs the interface?
For example, I refer to my actual class like so:
Hashtable<String,String> foo() {
Hashtable<String,String> table = new Hashtable<String,String>(100);
....
return table;
}
...
Hashtable<String,String> tbl = foo();
VS
Map<String,String> foo() {
Map<String,String> table = new Hashtable<String,String>(100);
....
return table;
}
...
Map<String,String> tbl = foo();
Will the first form be more efficient?
OK, summarizing the answers now. I wish I could mark both Thomas and Tagir as correct, but I can't.
Thomas is correct in that the "correct" behavior is to use the abstract interface (Map) rather than the concrete implementation (Hashtable). This is the proper abstraction of the data and allows for the underlying implementation to be changed at will.
Tagir is correct in that exposing the concrete class allows certain compiler optimizations -- possibly highly significant optimizations. However, knowing if this will work or not requires knowledge of the compiler internals or benchmarking, and is not portable. It probably does not work for Android.
Finally, if you care about performance, don't use Hashtable; it's obsolete and clunky. If you really care about performance, consider using arrays instead.
In terms of runtime efficiency both should be equal as in both cases a Hashtable is used.
In terms of design using Map would be better in most cases, i.e. when it is irrelevant which implementation of Map is used. Generally you should use interfaces where possible so that you can replace the implementation, e.g. use a HashMap instead.
The difference between Hashtable and HashMap for example, would mainly be due to thread safety, i.e. Hashtable is synchronized and thus threadsafe while HashMap yields better performance due to the lack of synchronization. If you'd use Map in your interface you could also use ConcurrentHashMap without having to change the caller and get thread safety along with performance (although I'm not sure about how much difference there would be between ConcurrentHashMap an Hashtable).
Apart from the fact that using Hashtable is itself a crime against performance (acquires a lock on each method call), the advantage of using a concrete class will only give a slight advantage to non-JIT-compiled code because the class's vtable can be reached directly, as opposed to a linear search through the itable lookup array, plus a dereference to the actual itable. The overhead of this search would become significant only if a class implemented many interfaces, which is not the case for Hashtable.
Unless your call sites dispatch to many different implementations of Map (hardly likely), the JIT-compiled code will be as efficent as if you used the concrete type on the variable. And for the simplest case where you say
Map<K,V> m = new Hashtable<>();
even the interpreter can statically determine that m will always point to a Hashtable and optimize accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With