Hello Struts developers, I'd like to humbly submit an updated version of "filter" in org.apache.struts.util.ResponseUtils, which should significantly increase its performance. I hope this is the right way to do it.
This method escapes HTML reserved characters in a String in the
straightforward way. From prior work, I've got an optimized method that does
just the same thing. The patch is included at the bottom; for reference,
here is what I am proposing for this method:
public static String filter(String value) {
if (value == null || value.length() == 0)
return (value);
char[] content = value.toCharArray();
int size = content.length;
StringBuffer result = new StringBuffer(size + 50);
int mark = 0;
String replacement = null;
for (int i = 0; i < size; i++) {
switch (content[i]) {
case '<':
replacement = "<";
break;
case '>':
replacement = ">";
break;
case '&':
replacement = "&";
break;
case '"':
replacement = """;
break;
}
if (replacement != null) {
if (mark < i) {
result.append(content, mark, i-mark);
}
result.append(replacement);
replacement = null;
mark = i+1;
}
}
if (mark < size) {
result.append(content, mark, size-mark);
}
return (result.toString());
}
The difference is essentially consolidation of many calls to
StringBuffer.append(char) into a few calls to StringBuffer.append(char[],
int, int). It's also faster on empty Strings, which I believe is a common
case.
This has been thoroughly tested and I can report that it produces the same
output, with 10-50% faster execution "on average", based on my rough
estimation of what input is usually fed into this method (the performance
difference is larger when the input has relatively few HTML reserved
characters, which fortunately is normal). Excepting rare cases (e.g.
"<<>>"), it's at least as fast as the original.
I realize that this offers quite minor overall performance improvement at
best, but since the method is called relatively often at runtime, and
because the change is isolated, I thought it would be reasonable to suggest
it.
Thanks, especially for any feedback you can offer!
Sean
Index: ResponseUtils.java
===================================================================
RCS file:
/home/cvspublic/jakarta-struts/src/share/org/apache/struts/util/ResponseUtil
s.java,v
retrieving revision 1.3
diff -u -r1.3 ResponseUtils.java
--- ResponseUtils.java 2001/02/13 17:27:20 1.3
+++ ResponseUtils.java 2001/12/16 01:24:57
@@ -76,6 +76,7 @@
* in the Struts controller framework.
*
* @author Craig R. McClanahan
+ * @author Sean Owen
* @version $Revision: 1.3 $ $Date: 2001/02/13 17:27:20 $
*/
@@ -106,29 +107,40 @@
*/
public static String filter(String value) {
- if (value == null)
- return (null);
-
- char content[] = new char[value.length()];
- value.getChars(0, value.length(), content, 0);
- StringBuffer result = new StringBuffer(content.length + 50);
- for (int i = 0; i < content.length; i++) {
+ if (value == null || value.length() == 0)
+ return (value);
+
+ char[] content = value.toCharArray();
+ int size = content.length;
+ StringBuffer result = new StringBuffer(size + 50);
+ int mark = 0;
+ String replacement = null;
+ for (int i = 0; i < size; i++) {
switch (content[i]) {
case '<':
- result.append("<");
+ replacement = "<";
break;
case '>':
- result.append(">");
+ replacement = ">";
break;
case '&':
- result.append("&");
+ replacement = "&";
break;
case '"':
- result.append(""");
+ replacement = """;
break;
- default:
- result.append(content[i]);
}
+ if (replacement != null) {
+ if (mark < i) {
+ result.append(content, mark, i-mark);
+ }
+ result.append(replacement);
+ replacement = null;
+ mark = i+1;
+ }
+ }
+ if (mark < size) {
+ result.append(content, mark, size-mark);
}
return (result.toString());
smime.p7s
Description: application/pkcs7-signature
