Replace recursive concatenations StringBuffer by append in a single StringBuffer. Goal is performance.

This commit is contained in:
Christian P. MOMON 2010-02-25 16:19:28 +01:00
parent 61f799d21f
commit ce92d363f4
9 changed files with 84 additions and 94 deletions

View file

@ -44,22 +44,24 @@ class XidDemo
datas = new Data (); datas = new Data ();
datas.setContent ("name", "Superman"); datas.setContent ("name", "Superman");
StringBuffer html; String htmlSource = "<div id='name'>a name</div >";
StringBuffer htmlTarget;
try try
{ {
html = StringPresenter.doXid ("<div id='name'>a name</div >", datas); htmlTarget = StringPresenter.doXid (htmlSource, datas);
} }
catch (Exception exception) catch (Exception exception)
{ {
System.out.println(exception.getMessage()); System.out.println(exception.getMessage());
html = null; htmlTarget = null;
} }
System.out.println ("datas = new Data ();"); System.out.println ("datas = new Data ();");
System.out.println ("datas.setContent (\"name\", \"Superman\");"); System.out.println ("datas.setContent (\"name\", \"Superman\");");
System.out.println ("+"); System.out.println ("+");
System.out.println ("<div id='name'>a name</div >"); System.out.println ("<div id='name'>a name</div >");
System.out.println ("=>"); System.out.println ("=>");
System.out.println (html); System.out.println (htmlTarget);
System.out.println ("[" + htmlSource.length() + "] => [" + htmlTarget.length() + "]");
} }
@ -73,15 +75,16 @@ class XidDemo
datas.appendAttribute ("lastname", "style", "foreground: red;"); datas.appendAttribute ("lastname", "style", "foreground: red;");
datas.setAttribute ("lastname", "class", "nameClass"); datas.setAttribute ("lastname", "class", "nameClass");
StringBuffer html; String htmlSource = "<div id='lastname'>a last name</div >";
StringBuffer htmlTarget;
try try
{ {
html = StringPresenter.doXid ("<div id='lastname'>a last name</div >", datas); htmlTarget = StringPresenter.doXid (htmlSource, datas);
} }
catch (Exception exception) catch (Exception exception)
{ {
System.out.println(exception.getMessage()); System.out.println(exception.getMessage());
html = null; htmlTarget = null;
} }
System.out.println ("datas = new Data ();"); System.out.println ("datas = new Data ();");
@ -92,7 +95,8 @@ class XidDemo
System.out.println ("+"); System.out.println ("+");
System.out.println ("<div id='lastname'>a last name</div>"); System.out.println ("<div id='lastname'>a last name</div>");
System.out.println ("=>"); System.out.println ("=>");
System.out.println (html); System.out.println (htmlTarget);
System.out.println ("[" + htmlSource.length() + "] => [" + htmlTarget.length() + "]");
} }
@ -108,15 +112,16 @@ class XidDemo
datas.setContent ("words", 4, "echo"); datas.setContent ("words", 4, "echo");
datas.setContent ("words", 5, "fox"); datas.setContent ("words", 5, "fox");
StringBuffer html; String htmlSource = "<ul>\n <li id='words'>a word</li>\n</ul>";
StringBuffer htmlTarget;
try try
{ {
html = StringPresenter.doXid ("<ul>\n <li id='words'>a word</li>\n</ul>", datas); htmlTarget = StringPresenter.doXid (htmlSource, datas);
} }
catch (Exception exception) catch (Exception exception)
{ {
System.out.println(exception.getMessage()); System.out.println(exception.getMessage());
html = null; htmlTarget = null;
} }
System.out.println ("datas = new Data ();"); System.out.println ("datas = new Data ();");
@ -131,7 +136,8 @@ class XidDemo
System.out.println (" <li id='words'>a word</li>"); System.out.println (" <li id='words'>a word</li>");
System.out.println ("</ul>"); System.out.println ("</ul>");
System.out.println ("=>"); System.out.println ("=>");
System.out.println (html); System.out.println (htmlTarget);
System.out.println ("[" + htmlSource.length() + "] => [" + htmlTarget.length() + "]");
} }
@ -154,15 +160,15 @@ class XidDemo
source.append ("</table>"); source.append ("</table>");
String htmlSource = source.toString (); String htmlSource = source.toString ();
StringBuffer html; StringBuffer htmlTarget;
try try
{ {
html = StringPresenter.doXid (htmlSource, datas); htmlTarget = StringPresenter.doXid (htmlSource, datas);
} }
catch (Exception exception) catch (Exception exception)
{ {
System.out.println(exception.getMessage()); System.out.println(exception.getMessage());
html = null; htmlTarget = null;
} }
System.out.println ("datas = new Data ();"); System.out.println ("datas = new Data ();");
@ -176,7 +182,8 @@ class XidDemo
System.out.println ("+"); System.out.println ("+");
System.out.println (htmlSource); System.out.println (htmlSource);
System.out.println ("=>"); System.out.println ("=>");
System.out.println (html); System.out.println (htmlTarget);
System.out.println ("[" + htmlSource.length() + "] => [" + htmlTarget.length() + "]");
} }

View file

@ -116,7 +116,8 @@ public class DomPresenter extends Presenter
else else
{ {
// Build the web page. // Build the web page.
result = Presenter.doXid (this.doc, datas); result = new StringBuffer ();
Presenter.doXid (result, this.doc, datas);
} }
// //
@ -127,11 +128,12 @@ public class DomPresenter extends Presenter
/* /*
* Xid a file with data. * Xid a file with data.
*/ */
static public StringBuffer doXid (Document doc, IdsDataById datas, String webappPath) throws Exception static public StringBuffer doXid (Document doc, IdsDataById datas) throws Exception
{ {
StringBuffer result; StringBuffer result;
result = Presenter.process (doc, datas, webappPath); result = new StringBuffer();
Presenter.process (result, doc, datas);
// //
return (result); return (result);

View file

@ -113,7 +113,8 @@ public class FilePresenter extends DomPresenter
} }
// Build the web page. // Build the web page.
result = Presenter.doXid (doc, datas); result = new StringBuffer (Presenter.estimatedTargetLength(source.length()));
Presenter.doXid (result, doc, datas);
// //
return (result); return (result);
@ -123,32 +124,7 @@ public class FilePresenter extends DomPresenter
/* /*
* Xid a file without data. * Xid a file without data.
*/ */
static public StringBuffer doXid (String fileName) throws Exception static public StringBuffer doXid (String filePathname) throws Exception
{
StringBuffer result;
Document doc = Presenter.fileToTree (fileName);
if (doc == null)
{
result = null;
}
else
{
Presenter.addMetaTag (doc, "generator", "XID 0.0");
result = Presenter.doXid (doc, null);
}
//
return (result);
}
/*
* Xid a file without data.
*/
static public StringBuffer doXid2 (String filePathname) throws Exception
{ {
StringBuffer result; StringBuffer result;

View file

@ -25,14 +25,9 @@ public class Presenter
/* /*
* Xid a file with data. * Xid a file with data.
*/ */
static public StringBuffer doXid (Document doc, IdsDataById datas) throws Exception static public void doXid (StringBuffer result, Document doc, IdsDataById datas) throws Exception
{ {
StringBuffer result; Presenter.process (result, doc, datas);
result = Presenter.process (doc, datas);
//
return (result);
} }
@ -117,27 +112,20 @@ public class Presenter
/* /*
* *
*/ */
static protected StringBuffer processChildren (Node node, IdsDataById datas) throws Exception static protected void processChildren (StringBuffer result, Node node, IdsDataById datas) throws Exception
{ {
StringBuffer result; processChildren (result, node, datas, "");
result = processChildren (node, datas, "");
//
return (result);
} }
/* /*
* *
*/ */
static protected StringBuffer processChildren (Node node, static protected void processChildren (StringBuffer result,
Node node,
IdsDataById datas, IdsDataById datas,
String suffix) throws Exception String suffix) throws Exception
{ {
StringBuffer result;
result = new StringBuffer ();
// Get the iteration strategy. // Get the iteration strategy.
IdData.IterationStrategy strategy; IdData.IterationStrategy strategy;
@ -189,12 +177,12 @@ public class Presenter
lineCounter += 1; lineCounter += 1;
if (lineCounter == 1) if (lineCounter == 1)
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
else else
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
break; break;
@ -209,12 +197,12 @@ public class Presenter
if ((lineCounter == 1) || (lineCounter == 2)) if ((lineCounter == 1) || (lineCounter == 2))
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
else else
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
break; break;
@ -229,12 +217,12 @@ public class Presenter
if ((attrs2 != null) && if ((attrs2 != null) &&
(attrs2.getNamedItem ("id") != null)) (attrs2.getNamedItem ("id") != null))
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
else else
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
break; break;
@ -248,12 +236,12 @@ public class Presenter
if ((attrs2 == null) || if ((attrs2 == null) ||
(attrs2.getNamedItem ("id") == null)) (attrs2.getNamedItem ("id") == null))
{ {
result.append (process (children.item(childIndex), datas, suffix)); process (result, children.item(childIndex), datas, suffix);
} }
} }
else else
{ {
result.append (process (children.item (childIndex), datas, suffix)); process (result, children.item (childIndex), datas, suffix);
} }
} }
break; break;
@ -261,13 +249,10 @@ public class Presenter
case ALL_ROWS: case ALL_ROWS:
for (int childIndex = 0; childIndex < childrenCount; childIndex++) for (int childIndex = 0; childIndex < childrenCount; childIndex++)
{ {
result.append (process (children.item(childIndex), datas, suffix)); process (result, children.item(childIndex), datas, suffix);
} }
break; break;
} }
//
return (result);
} }
@ -370,7 +355,7 @@ public class Presenter
if ((data == null) || if ((data == null) ||
(data.display () == null)) (data.display () == null))
{ {
result.append (processChildren (node, datas, suffix)); processChildren (result, node, datas, suffix);
} }
else else
{ {
@ -417,7 +402,7 @@ public class Presenter
// Insert data. // Insert data.
if ((data == null) || (data.display () == null)) if ((data == null) || (data.display () == null))
{ {
result.append (processChildren (node, datas, suffix)); processChildren (result, node, datas, suffix);
} }
else else
{ {
@ -455,14 +440,9 @@ public class Presenter
/** /**
* *
*/ */
static protected StringBuffer process (Node node, IdsDataById datas) throws Exception static protected void process (StringBuffer result, Node node, IdsDataById datas) throws Exception
{ {
StringBuffer result; Presenter.process (result, node, datas, "");
result = Presenter.process (node, datas, "");
//
return (result);
} }
@ -470,16 +450,13 @@ public class Presenter
* Recursive method that processes a node and any child nodes. * Recursive method that processes a node and any child nodes.
* *
*/ */
static protected StringBuffer process (Node node, IdsDataById datas, String suffix) throws Exception static protected void process (StringBuffer result, Node node, IdsDataById datas, String suffix) throws Exception
{ {
logger.debug ("process - started"); logger.debug ("process - started");
String TRANSITIONAL_DTD = "xhtml1-transitional.dtd"; String TRANSITIONAL_DTD = "xhtml1-transitional.dtd";
String TRANSITIONAL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " String TRANSITIONAL_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 "
+ "Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; + "Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
StringBuffer result;
result = new StringBuffer ();
// Is there anything to do? // Is there anything to do?
if (node != null) if (node != null)
{ {
@ -514,7 +491,7 @@ public class Presenter
// Log.write(Log.TRACE,"systemId = " + systemId); // Log.write(Log.TRACE,"systemId = " + systemId);
} }
result.append (Presenter.process (((Document) node).getDocumentElement(), datas, suffix)); Presenter.process (result, ((Document) node).getDocumentElement(), datas, suffix);
break; break;
} }
@ -596,7 +573,6 @@ public class Presenter
// //
//logger.info ("result=" + result); //logger.info ("result=" + result);
logger.debug ("process - ended"); logger.debug ("process - ended");
return (result);
} }
@ -644,7 +620,7 @@ public class Presenter
{ {
result.append('>'); result.append('>');
result.append (processChildren (node, datas, suffix)); processChildren (result, node, datas, suffix);
result.append("</"); result.append("</");
result.append(node.getNodeName()); result.append(node.getNodeName());
@ -1101,4 +1077,33 @@ public class Presenter
// //
return (result); return (result);
} }
/**
* Good estimation of the target length able to optimize performance.
*/
static int estimatedTargetLength(long sourceLength)
{
int result;
if (sourceLength < 1000)
{
result = (int) (sourceLength*5);
}
else if (sourceLength < 50000)
{
result = (int) (sourceLength*2);
}
else if (sourceLength < 800000)
{
result = (int) (100000);
}
else
{
result = (int) (sourceLength + 30000);
}
//
return(result);
}
} }

View file

@ -98,8 +98,8 @@ public class StringPresenter extends DomPresenter
doc = buildTree (new ByteArrayInputStream (htmlSource.getBytes ())); doc = buildTree (new ByteArrayInputStream (htmlSource.getBytes ()));
} }
StringBuffer htmlTarget; StringBuffer htmlTarget = new StringBuffer (Presenter.estimatedTargetLength(this.html.length()));
htmlTarget = Presenter.doXid (doc, datas); Presenter.doXid (htmlTarget, doc, datas);
if (htmlTarget == null) if (htmlTarget == null)
{ {