You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/12/16 23:24:40 UTC

svn commit: r1215318 - in /myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets: FaceletCompositionContext.java impl/DefaultFaceletContext.java impl/FaceletCompositionContextImpl.java impl/SectionUniqueIdCounter.java

Author: lu4242
Date: Fri Dec 16 22:24:40 2011
New Revision: 1215318

URL: http://svn.apache.org/viewvc?rev=1215318&view=rev
Log:
MYFACES-3427 [perf] Use only one StringBuilder for generate unique facelets identifiers

Modified:
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
    myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java?rev=1215318&r1=1215317&r2=1215318&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java Fri Dec 16 22:24:40 2011
@@ -44,7 +44,8 @@ abstract public class FaceletComposition
     
     static public FaceletCompositionContext getCurrentInstance()
     {
-        return (FaceletCompositionContext) FacesContext.getCurrentInstance().getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
+        return (FaceletCompositionContext)
+                FacesContext.getCurrentInstance().getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
     }
     
     static public FaceletCompositionContext getCurrentInstance(FaceletContext ctx)
@@ -58,7 +59,8 @@ abstract public class FaceletComposition
             // Here we have two choices: retrieve it throught ThreadLocal var
             // or use the attribute value on FacesContext, but it seems better
             // use the FacesContext attribute map.
-            return (FaceletCompositionContext) ctx.getFacesContext().getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
+            return (FaceletCompositionContext)
+                    ctx.getFacesContext().getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
         }
     }
     
@@ -204,23 +206,25 @@ abstract public class FaceletComposition
      * 
      * @param validatorId
      * @param attachedObjectHandler
-     * @since 2.0.8
+     * @since 2.0.10
      */
-    public abstract void pushEnclosingValidatorIdToStack(String validatorId, EditableValueHolderAttachedObjectHandler attachedObjectHandler);
+    public abstract void pushEnclosingValidatorIdToStack(String validatorId, 
+            EditableValueHolderAttachedObjectHandler attachedObjectHandler);
 
     /**
      * Gets all validationIds with its associated EditableValueHolderAttachedObjectHandler from the stack.
      * 
      * @return
-     * @since 2.0.8
+     * @since 2.0.10
      */
-    public abstract Iterator<Map.Entry<String, EditableValueHolderAttachedObjectHandler>> getEnclosingValidatorIdsAndHandlers();
+    public abstract Iterator<Map.Entry<String, EditableValueHolderAttachedObjectHandler>> 
+        getEnclosingValidatorIdsAndHandlers();
     
     /**
      * 
      * @param id
      * @return
-     * @since 2.0.8
+     * @since 2.0.10
      */
     public abstract boolean containsEnclosingValidatorId(String id);
     
@@ -304,7 +308,7 @@ abstract public class FaceletComposition
      * Marks all direct children and Facets with an attribute for deletion.
      *
      * @since 2.0.2
-     * @see #finalizeForDeletion(FaceletCompositionContext, UIComponent)
+     * @see #finalizeForDeletion(UIComponent)
      * @param component
      *            UIComponent to mark
      */
@@ -323,11 +327,12 @@ abstract public class FaceletComposition
      * Add a method expression as targeted for the provided composite component
      * 
      * @since 2.0.3
-     * @param compositeComponentParent
+     * @param targetedComponent
      * @param attributeName
      * @param backingValue A value that could be useful to revert its effects.
      */
-    public abstract void addMethodExpressionTargeted(UIComponent targetedComponent, String attributeName, Object backingValue);
+    public abstract void addMethodExpressionTargeted(UIComponent targetedComponent, String attributeName,
+                                                     Object backingValue);
 
     /**
      * Check if the MethodExpression attribute has been applied using vdl.retargetMethodExpression 
@@ -337,7 +342,8 @@ abstract public class FaceletComposition
      * @param attributeName
      * @return
      */
-    public abstract boolean isMethodExpressionAttributeApplied(UIComponent compositeComponentParent, String attributeName);
+    public abstract boolean isMethodExpressionAttributeApplied(UIComponent compositeComponentParent,
+                                                               String attributeName);
     
     /**
      * Mark the MethodExpression attribute as applied using vdl.retargetMethodExpression
@@ -361,7 +367,7 @@ abstract public class FaceletComposition
      * Remove a method expression as targeted for the provided composite component
      * 
      * @since 2.0.3
-     * @param compositeComponentParent
+     * @param targetedComponent
      * @param attributeName
      * @return A value that could be useful to revert its effects.
      */
@@ -414,6 +420,10 @@ abstract public class FaceletComposition
         return null;
     }
     
+    public void generateUniqueId(StringBuilder builderToAdd)
+    {
+    }
+    
     /**
      * Generate a unique id for component instances. 
      * 

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java?rev=1215318&r1=1215317&r2=1215318&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java Fri Dec 16 22:24:40 2011
@@ -21,12 +21,10 @@ package org.apache.myfaces.view.facelets
 import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import javax.el.ELContext;
@@ -59,7 +57,8 @@ import org.apache.myfaces.view.facelets.
  * Default FaceletContext implementation.
  * 
  * A single FaceletContext is used for all Facelets involved in an invocation of
- * {@link org.apache.myfaces.view.facelets.Facelet#apply(FacesContext, UIComponent) Facelet#apply(FacesContext, UIComponent)}. This
+ * {@link org.apache.myfaces.view.facelets.Facelet#apply(FacesContext, UIComponent)
+ * Facelet#apply(FacesContext, UIComponent)}. This
  * means that included Facelets are treated the same as the JSP include directive.
  * 
  * @author Jacob Hookom
@@ -314,71 +313,13 @@ final class DefaultFaceletContext extend
         // the final id will be unique, but prefix and base ensure it will be unique
         // per facelet because prefix is calculated from faceletHierarchy and base is
         // related to the tagId, which depends on the location.
-        _uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
+        //_uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
+        getFaceletCompositionContext().generateUniqueId(_uniqueIdBuilder);
         _uniqueIdBuilder.append("_");
         _uniqueIdBuilder.append(_prefix);
         _uniqueIdBuilder.append("_");
         _uniqueIdBuilder.append(base);
         return _uniqueIdBuilder.toString();
-        /*
-        if (_prefix == null)
-        {
-            StringBuilder builder = new StringBuilder(
-                    _faceletHierarchy.size() * 30);
-            for (int i = 0; i < _faceletHierarchy.size(); i++)
-            {
-                AbstractFacelet facelet = _faceletHierarchy.get(i);
-                builder.append(facelet.getAlias());
-            }
-
-            // Integer prefixInt = new Integer(builder.toString().hashCode());
-            // -= Leonardo Uribe =- if the previous formula is used, it is possible that
-            // negative values are introduced. The presence of '-' char causes problems
-            // with htmlunit 2.4 or lower, so in order to prevent it it is better to use
-            // only positive values instead.
-            // Take into account CompilationManager.nextTagId() uses Math.abs too.
-            Integer prefixInt = new Integer(Math.abs(builder.toString().hashCode()));
-
-            Integer cnt = _prefixes.get(prefixInt);
-            if (cnt == null)
-            {
-                _prefixes.put(prefixInt, Integer.valueOf(0));
-                _prefix = prefixInt.toString();
-            }
-            else
-            {
-                int i = cnt.intValue() + 1;
-                _prefixes.put(prefixInt, Integer.valueOf(i));
-                _prefix = prefixInt + "_" + i;
-            }
-        }
-
-        Integer cnt = _ids.get(base);
-        if (cnt == null)
-        {
-            _ids.put(base, Integer.valueOf(0));
-            _uniqueIdBuilder.delete(0, _uniqueIdBuilder.length());
-            _uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
-            _uniqueIdBuilder.append("_");
-            _uniqueIdBuilder.append(_prefix);
-            _uniqueIdBuilder.append("_");
-            _uniqueIdBuilder.append(base);
-            return _uniqueIdBuilder.toString();
-        }
-        else
-        {
-            int i = cnt.intValue() + 1;
-            _ids.put(base, Integer.valueOf(i));
-            _uniqueIdBuilder.delete(0, _uniqueIdBuilder.length());
-            _uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
-            _uniqueIdBuilder.append("_");
-            _uniqueIdBuilder.append(_prefix);
-            _uniqueIdBuilder.append("_");
-            _uniqueIdBuilder.append(base);
-            _uniqueIdBuilder.append("_");
-            _uniqueIdBuilder.append(i);
-            return _uniqueIdBuilder.toString();
-        }*/
     }
 
     /**
@@ -495,7 +436,8 @@ final class DefaultFaceletContext extend
         //    found = client.apply(this, parent, name);
         //}
         //return found;
-        return _isolatedTemplateContext.get(_currentTemplateContext).includeDefinition(this, this._facelet, parent, name);
+        return _isolatedTemplateContext.get(_currentTemplateContext).includeDefinition(
+                this, this._facelet, parent, name);
     }
 
     /*
@@ -593,7 +535,8 @@ final class DefaultFaceletContext extend
             _isolatedTemplateContext.add(new IsolatedTemplateContextImpl());
         }
         _currentTemplateContext++;
-        _isolatedTemplateContext.get(_currentTemplateContext).setCompositeComponentClient( new CompositeComponentTemplateManager(this._facelet, client));
+        _isolatedTemplateContext.get(_currentTemplateContext).setCompositeComponentClient(
+            new CompositeComponentTemplateManager(this._facelet, client));
     }
     
     @Override
@@ -617,7 +560,8 @@ final class DefaultFaceletContext extend
     public void pushCompositeComponentClient(final TemplateClient client)
     {
         TemplateContext itc = new TemplateContextImpl();
-        itc.setCompositeComponentClient(new CompositeComponentTemplateManager(this._facelet, client, getPageContext()));
+        itc.setCompositeComponentClient(
+                new CompositeComponentTemplateManager(this._facelet, client, getPageContext()));
         _isolatedTemplateContext.add(itc);
         _currentTemplateContext++;
         _defaultVarMapper.setTemplateContext(itc);
@@ -744,6 +688,13 @@ final class DefaultFaceletContext extend
             return this._owner == o || this._target == o;
         }
 
+        @Override
+        public int hashCode()
+        {
+            int result = _owner != null ? _owner.hashCode() : 0;
+            result = 31 * result + (_target != null ? _target.hashCode() : 0);
+            return result;
+        }
     }
     
     @Override
@@ -861,7 +812,8 @@ final class DefaultFaceletContext extend
     
     public boolean isAllowCacheELExpressions()
     {
-        return _isCacheELExpressions && getTemplateContext().isAllowCacheELExpressions() && getPageContext().isAllowCacheELExpressions();
+        return _isCacheELExpressions && getTemplateContext().isAllowCacheELExpressions() 
+                && getPageContext().isAllowCacheELExpressions();
     }
     
     public void beforeConstructELExpression()

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java?rev=1215318&r1=1215317&r2=1215318&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java Fri Dec 16 22:24:40 2011
@@ -47,30 +47,38 @@ import org.apache.myfaces.view.facelets.
 public class FaceletCompositionContextImpl extends FaceletCompositionContext
 {
     /**
-     * Indicates if expressions generated by facelets should be cached or not. Default is noCache. There there are four modes:
+     * Indicates if expressions generated by facelets should be cached or not.
+     * Default is noCache. There there are four modes:
      * 
      * <ul>
-     * <li>always: Only does not cache when expressions are inside user tags or the expression contains a variable resolved using VariableMapper</li>
-     * <li>allowCset: Like always, but does not allow cache when ui:param was used on the current template context</li>
-     * <li>strict: Like allowCset, but does not allow cache when c:set with var and value properties only is used on the current page context</li>
+     * <li>always: Only does not cache when expressions are inside user tags or the e
+     * xpression contains a variable resolved using VariableMapper</li>
+     * <li>allowCset: Like always, but does not allow cache when ui:param
+     * was used on the current template context</li>
+     * <li>strict: Like allowCset, but does not allow cache when c:set with
+     * var and value properties only is used on the current page context</li>
      * <li>noCache: All expression are created each time the view is built</li>
      * </ul>
      * 
      */
-    @JSFWebConfigParam(since="2.0.8", defaultValue="noCache", expectedValues="noCache, strict, allowCset, always", group="EL", tags="performance")
+    @JSFWebConfigParam(since="2.0.8", defaultValue="noCache", expectedValues="noCache, strict, allowCset, always",
+                       group="EL", tags="performance")
     public static final String INIT_PARAM_CACHE_EL_EXPRESSIONS = "org.apache.myfaces.CACHE_EL_EXPRESSIONS";
     
     /**
-     * Wrap exception caused by calls to EL expressions, so information like the location, expression string and tag name can be retrieved by
+     * Wrap exception caused by calls to EL expressions, so information like
+     * the location, expression string and tag name can be retrieved by
      * the ExceptionHandler implementation and used to output meaningful information about itself.
      * 
-     * <p>Note in some cases this will wrap the original javax.el.ELException, so the information will not be on the stack trace unless ExceptionHandler
+     * <p>Note in some cases this will wrap the original javax.el.ELException,
+     * so the information will not be on the stack trace unless ExceptionHandler
      * retrieve checking if the exception implements ContextAware interface and calling getWrapped() method.
      * </p>
      * 
      */
     @JSFWebConfigParam(since="2.0.9, 2.1.3" , defaultValue="true", expectedValues="true, false")
-    public static final String INIT_PARAM_WRAP_TAG_EXCEPTIONS_AS_CONTEXT_AWARE = "org.apache.myfaces.WRAP_TAG_EXCEPTIONS_AS_CONTEXT_AWARE";
+    public static final String INIT_PARAM_WRAP_TAG_EXCEPTIONS_AS_CONTEXT_AWARE
+            = "org.apache.myfaces.WRAP_TAG_EXCEPTIONS_AS_CONTEXT_AWARE";
     
     private FacesContext _facesContext;
     
@@ -305,7 +313,8 @@ public class FaceletCompositionContextIm
     {
         if (_enclosingValidatorIdsStack != null && !_enclosingValidatorIdsStack.isEmpty())
         {
-            return new KeyEntryIterator<String, EditableValueHolderAttachedObjectHandler>(_enclosingValidatorIdsStack.iterator()); 
+            return new KeyEntryIterator<String, EditableValueHolderAttachedObjectHandler>
+                (_enclosingValidatorIdsStack.iterator()); 
         }
         return null;
     }
@@ -335,14 +344,18 @@ public class FaceletCompositionContextIm
     }
     
     @Override
-    public void pushEnclosingValidatorIdToStack(String validatorId, EditableValueHolderAttachedObjectHandler attachedObjectHandler)
+    public void pushEnclosingValidatorIdToStack(String validatorId, 
+            EditableValueHolderAttachedObjectHandler attachedObjectHandler)
     {
         if (_enclosingValidatorIdsStack == null)
         {
-            _enclosingValidatorIdsStack = new LinkedList<Map.Entry<String, EditableValueHolderAttachedObjectHandler>>();
+            _enclosingValidatorIdsStack = 
+                new LinkedList<Map.Entry<String, EditableValueHolderAttachedObjectHandler>>();
         }
 
-        _enclosingValidatorIdsStack.addFirst(new SimpleEntry<String, EditableValueHolderAttachedObjectHandler>(validatorId, attachedObjectHandler));
+        _enclosingValidatorIdsStack.addFirst(
+                new SimpleEntry<String, EditableValueHolderAttachedObjectHandler>
+                    (validatorId, attachedObjectHandler));
     }
 
     public Iterator<Map.Entry<String, EditableValueHolderAttachedObjectHandler>> getEnclosingValidatorIdsAndHandlers()
@@ -424,7 +437,8 @@ public class FaceletCompositionContextIm
         if (_elExpressionCacheMode == null)
         {
             String value = WebConfigParamUtils.getStringInitParameter(
-                    _facesContext.getExternalContext(), INIT_PARAM_CACHE_EL_EXPRESSIONS, ELExpressionCacheMode.noCache.name());
+                    _facesContext.getExternalContext(),
+                    INIT_PARAM_CACHE_EL_EXPRESSIONS, ELExpressionCacheMode.noCache.name());
             
             _elExpressionCacheMode = Enum.valueOf(ELExpressionCacheMode.class, value); 
         }
@@ -436,7 +450,8 @@ public class FaceletCompositionContextIm
     {
         if (_isWrapTagExceptionsAsContextAware == null)
         {
-            _isWrapTagExceptionsAsContextAware = WebConfigParamUtils.getBooleanInitParameter(_facesContext.getExternalContext(),
+            _isWrapTagExceptionsAsContextAware
+                    = WebConfigParamUtils.getBooleanInitParameter(_facesContext.getExternalContext(),
                     INIT_PARAM_WRAP_TAG_EXCEPTIONS_AS_CONTEXT_AWARE, true);
         }
         return _isWrapTagExceptionsAsContextAware;
@@ -482,18 +497,6 @@ public class FaceletCompositionContextIm
         map.put(attributeName, backingValue);
     }
 
-    /*
-    @Override
-    public Map<String, Object> getMethodExpressionsTargeted(UIComponent compositeComponentParent)
-    {
-        Map<String, Object> map = _methodExpressionsTargeted.get(compositeComponentParent);
-        if (map == null)
-        {
-            map = Collections.emptyMap();
-        }
-        return map;
-    }*/
-    
     public boolean isMethodExpressionAttributeApplied(UIComponent compositeComponentParent, String attributeName)
     {
         Map<String, Boolean> map = _compositeComponentAttributesMarked.get(compositeComponentParent);
@@ -681,7 +684,8 @@ public class FaceletCompositionContextIm
                 {
                     itr.remove();
                 }
-                else if ( id == null && Boolean.TRUE.equals(fc.getAttributes().get(ComponentSupport.FACET_CREATED_UIPANEL_MARKER)))
+                else if (id == null
+                         && Boolean.TRUE.equals(fc.getAttributes().get(ComponentSupport.FACET_CREATED_UIPANEL_MARKER)))
                 {
                     if (fc.getChildCount() > 0)
                     {
@@ -717,6 +721,11 @@ public class FaceletCompositionContextIm
         return _sectionUniqueIdCounter.generateUniqueId();
     }
     
+    public void generateUniqueId(StringBuilder builderToAdd)
+    {
+        _sectionUniqueIdCounter.generateUniqueId(builderToAdd);
+    }
+
     public String generateUniqueComponentId()
     {
         return _sectionUniqueComponentIdCounter.generateUniqueId();
@@ -796,30 +805,46 @@ public class FaceletCompositionContextIm
             return result;
         }
 
+        @SuppressWarnings("unchecked")
         @Override
         public boolean equals(Object obj)
         {
             if (this == obj)
+            {
                 return true;
+            }
             if (obj == null)
+            {
                 return false;
+            }
             if (getClass() != obj.getClass())
+            {
                 return false;
+            }
             SimpleEntry other = (SimpleEntry) obj;
             if (_key == null)
             {
                 if (other._key != null)
+                {
                     return false;
+                }
             }
             else if (!_key.equals(other._key))
+            {
                 return false;
+            }
+            
             if (_value == null)
             {
                 if (other._value != null)
+                {
                     return false;
+                }
             }
             else if (!_value.equals(other._value))
+            {
                 return false;
+            }
             return true;
         }
 

Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java?rev=1215318&r1=1215317&r2=1215318&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java Fri Dec 16 22:24:40 2011
@@ -37,6 +37,8 @@ public class SectionUniqueIdCounter
     
     private final StringBuilder _builder;
     
+    private char[] _bufferConversion;
+    
     private final int _radix;
    
     public SectionUniqueIdCounter()
@@ -47,6 +49,7 @@ public class SectionUniqueIdCounter
         _counterStack.add(new Section(null,1,_radix));
         _prefix = null;
         _builder = new StringBuilder(30);
+        _bufferConversion = new char[15];
     }
     
     public SectionUniqueIdCounter(String prefix)
@@ -57,6 +60,7 @@ public class SectionUniqueIdCounter
         _counterStack.add(new Section(null,1,_radix));
         _prefix = prefix;
         _builder = new StringBuilder(30);
+        _bufferConversion = new char[15];
     }
     
     public SectionUniqueIdCounter(String prefix, int radix)
@@ -67,6 +71,7 @@ public class SectionUniqueIdCounter
         _counterStack.add(new Section(null,1,_radix));
         _prefix = prefix;
         _builder = new StringBuilder(30);
+        _bufferConversion = new char[15];
     }
 
     public String startUniqueIdSection()
@@ -80,7 +85,8 @@ public class SectionUniqueIdCounter
             {
                 _builder.append('_');
             }
-            _builder.append(Long.toString(_counterStack.get(i).getCounter(), _radix));
+            //_builder.append(Long.toString(_counterStack.get(i).getCounter(), _radix));
+            appendToBuilder(_counterStack.get(i).getCounter(), _radix, _builder, _bufferConversion);
             added = true;
         }
         
@@ -100,7 +106,8 @@ public class SectionUniqueIdCounter
             {
                 _builder.append('_');
             }
-            _builder.append(Long.toString(_counterStack.get(i).getCounter(), _radix));
+            //_builder.append(Long.toString(_counterStack.get(i).getCounter(), _radix));
+            appendToBuilder(_counterStack.get(i).getCounter(), _radix, _builder, _bufferConversion);
             added = true;
         }
         if (base != null && base.length() > 0)
@@ -118,6 +125,11 @@ public class SectionUniqueIdCounter
         return _counterStack.get(_activeSection).generateUniqueId(_prefix);
     }
     
+    public void generateUniqueId(StringBuilder builderToAdd)
+    {
+        _counterStack.get(_activeSection).generateUniqueId(_prefix, builderToAdd);
+    }
+    
     public void endUniqueIdSection()
     {
         if (_activeSection <= 0)
@@ -133,11 +145,13 @@ public class SectionUniqueIdCounter
         }
     }
     
-    private static class Section {
+    private static class Section
+    {
         
         private String prefix;
         private long counter;
         private final StringBuilder _builder;
+        private char[] _bufferConversion;
         private final int _radix;
         
         public Section(String prefix, long counter, int radix)
@@ -146,6 +160,7 @@ public class SectionUniqueIdCounter
             this.prefix = prefix;
             this.counter = counter;
             _builder = new StringBuilder(30);
+            _bufferConversion = new char[15];
             _radix = radix;
         }
 
@@ -154,6 +169,27 @@ public class SectionUniqueIdCounter
             return counter;
         }
 
+        public void generateUniqueId(String base, StringBuilder builder)
+        {
+            long i = this.counter;
+            this.counter++;
+            //_builder.delete(0, _builder.length());
+            if (base != null)
+            {
+                builder.append(base);
+            }
+            if (this.prefix != null)
+            {
+                builder.append(this.prefix);
+                builder.append('_');
+            }
+            // By performance reasons, Long.toString is a very expensive
+            // operation in this location, because it triggers a new String()
+            //_builder.append(Long.toString(i, _radix));
+            appendToBuilder(i, _radix, builder, _bufferConversion);
+            //return _builder.toString();
+        }
+        
         public String generateUniqueId(String base)
         {
             long i = this.counter;
@@ -168,8 +204,68 @@ public class SectionUniqueIdCounter
                 _builder.append(this.prefix);
                 _builder.append('_');
             }
-            _builder.append(Long.toString(i, _radix));
+            // By performance reasons, Long.toString is a very expensive
+            // operation in this location, because it triggers a new String()
+            //_builder.append(Long.toString(i, _radix));
+            appendToBuilder(i, _radix, _builder, _bufferConversion);
             return _builder.toString();
         }
     }
+    
+    //From Harmony Long.toString(l,radix)
+    private static void appendToBuilder(long l, int radix, StringBuilder builder, char[] bufferConversion)
+    {
+        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+        {
+            radix = 10;
+        }
+        if (l == 0)
+        {
+            builder.append('0');
+            return;
+        }
+
+        int count = 2;
+        long j = l;
+        boolean negative = l < 0;
+        if (!negative)
+        {
+            count = 1;
+            j = -l;
+        }
+        while ((l /= radix) != 0) {
+            count++;
+        }
+
+        if (bufferConversion.length < count)
+        {
+            bufferConversion = new char[count];
+        }
+        int finalCount = count;
+
+        char[] buffer = bufferConversion;
+        do 
+        {
+            int ch = 0 - (int) (j % radix);
+            if (ch > 9)
+            {
+                ch = ch - 10 + 'a';
+            }
+            else
+            {
+                ch += '0';
+            }
+            buffer[--count] = (char) ch;
+        }
+        while ((j /= radix) != 0);
+        if (negative)
+        {
+            buffer[0] = '-';
+        }
+        for (int i = 0; i < finalCount; i++)
+        {
+            builder.append(buffer[i]);
+        }
+        //return new String(0, buffer.length, buffer);
+    }
 }