|
|
|
I know I'm bit late given this is closed, but would it have been possible to make this configurable? While String.intern() is slow, it can have other performance benefits beyond just reduced memory usage. As such there are cases where I would prefer to get intern()ed names back (apologies if I misunderstood this issue and it's only for internal usage of unified/canonical Strings). Basically nice thing about intern()ed Strings is that they can be == compared with String constants. This can not be done by library-unified Strings.
So it'd be nice if one could choose interning/non-interning behavior; defaulting to non-interning is fine since it's safer. The current implementation ensures that always the *same* string is used. So there's no reason to use inter(). It is slower, allocated valuable space and you gain nothing from such an option. However, you can easily register your own StringConverter if you insist on such a behaviour.
There is a small error in my implementation. The new WeakHashMap<String, String> is wrong, it has to be new WeakHashMap<String, WeakReference<String>>. Otherwise the map has strong references to its own weak keys. Check Java doc for more information.
So, the Converter code should look like this: /** * A Map to store strings as long as needed to map similar * strings onto the same instance and conserve memory. The map can be set * from the outside during construction, so it can be a lru map or a * weak map, sychronised or not. */ private final Map<String, WeakReference<String>> cache; public SRStringConverter(Map<String, WeakReference<String>> cache) { this.cache = cache; } public boolean canConvert(Class type) { return type.equals(String.class); } public Object fromString(String str) { String result = null; WeakReference<String> ref = cache.get(str); if (ref != null) { result = ref.get(); } if (result == null) { // fill cache cache.put(str, new WeakReference<String>(str)); result = str; } return result; } Check the last comment. It might be necessary to check my findings.
This is what already has been implemented. You might check the latest SNAPSHOT.
Thanks. So it was a problem in my code because I still use my own converter and have not upgraded yet.
|
||||||||||||||||||||||||||||||||||||||||||||
after some benchmarks it was visible that even the synchronized WeakHashMap is most times a lot faster than String.intern(). Therefore I've replaced our current implementation with yours and have the additional benefit of saving the limited PermGen space. This was really a great contribution. Thanks a lot! You may checkout the current version from Subversion to test yourself.
- Jörg