Revision: 4857 http://sourceforge.net/p/vexi/code/4857 Author: mkpg2 Date: 2016-05-18 22:27:02 +0000 (Wed, 18 May 2016) Log Message: ----------- Fix/Improve. String caching. - intern VML attr keys,values and literals, but only if less than 32 chars long (previous behaviour was inconsistent on this). This should be an improved heuristic. Not critical that values are interned at all, just a memory optimisation to do so. - cache JString only if < 32 characters long. Longer strings hanging in the cache (e.g. large generated html documents!) can be a serious quasi-memory leak.
Modified Paths: -------------- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/ExecParser.java branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java 2016-05-12 07:01:00 UTC (rev 4856) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java 2016-05-18 22:27:02 UTC (rev 4857) @@ -411,7 +411,7 @@ // convert attributes to appropriate types and intern strings for (int i=0; i<keysSize; i++) { // FEATURE: Intern - t.keys[i] = JSU.S((String)keys.get(i)); + t.keys[i] = JSU.S((String)keys.get(i), true); String valString = (String)vals.get(i); if (valString.equals("true")) { @@ -441,7 +441,7 @@ if (len > 0 && !hasNonNumeral) { t.vals[i] = JSU.N(periodUsed ? Double.parseDouble(valString) : Integer.parseInt(valString)); } else { - t.vals[i] = JSU.S(valString, true); + t.vals[i] = JSU.SmaybeIntern(valString); } } } Modified: branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/ExecParser.java =================================================================== --- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/ExecParser.java 2016-05-12 07:01:00 UTC (rev 4856) +++ branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/ExecParser.java 2016-05-18 22:27:02 UTC (rev 4857) @@ -36,6 +36,6 @@ public Object bool(boolean b) { return JSU.B(b); } public Object integer(int i) { return JSU.N(i); } public Object number(Number n) { return JSU.N(n); } - public Object string(String s) { return JSString.intern(s); } + public Object string(String s) { return JSU.SmaybeIntern(s); } public int toInt(Object o) { return ((JSNumber)o).toInt32(); } } Modified: branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java =================================================================== --- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java 2016-05-12 07:01:00 UTC (rev 4856) +++ branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/JSU.java 2016-05-18 22:27:02 UTC (rev 4857) @@ -188,15 +188,29 @@ public static final JS B(int i) { return i==0 ? F : T; } private static final int CACHE_SIZE = 65536 / 4; // must be a power of two - private static final JSString[] stringCache = new JSString[CACHE_SIZE]; + // REMARK _cannot_ use WeakHashMap here since the JSString (value) refers to the String (key), and this + // would mean keys would never get garbaged collected and the map would just permanently remember all strings ... + public static final JSString[] stringCache = new JSString[CACHE_SIZE]; public static final JS S(String s) { if(s == null) return null; - int slot = s.hashCode()&(CACHE_SIZE-1); - JSString ret = stringCache[slot]; - if(ret == null || !ret.s.equals(s)) stringCache[slot] = ret = new JSString(s); + // REMARK we do not want to bother caching longer strings ..., relative to string size the gain is + // pretty small. If large strings are being created multiple times, then really it is the programs + // responsibility to make sure the string objects are better reused. + JSString ret; + if(s.length()<=32){ + int slot = s.hashCode()&(CACHE_SIZE-1); + // SHOULD consider using something like a REFERENCEMAP for this.... + // This is a very rough and ready way of caching (obviously will have collision issues ... etc.), but + // has the advantage that it is going to be faste + ret = stringCache[slot]; + if(ret == null || !ret.s.equals(s)) stringCache[slot] = ret = new JSString(s); + }else{ + ret = new JSString(s); + } return ret; } static final public JS S(String s, boolean intern) { return intern ? JSString.intern(s) : S(s); } + static final public JS SmaybeIntern(String s) { return JSU.S(s,s.length()<=32); } static final public JS N(long l) { if(l<=Integer.MAX_VALUE && l>=Integer.MIN_VALUE) return JSU.N((int)l); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Mobile security can be enabling, not merely restricting. Employees who bring their own devices (BYOD) to work are irked by the imposition of MDM restrictions. Mobile Device Manager Plus allows you to control only the apps on BYO-devices by containerizing them, leaving personal data untouched! https://ad.doubleclick.net/ddm/clk/304595813;131938128;j _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn