提交 fef03d67 编写于 作者: M martin

6898220: Optimize Formatter.parse (including String.printf)

Summary: Create fewer objects when parsing
Reviewed-by: sherman
Contributed-by: NDaniel Martin <dtm@google.com>
上级 45d4a77f
...@@ -2485,55 +2485,45 @@ public final class Formatter implements Closeable, Flushable { ...@@ -2485,55 +2485,45 @@ public final class Formatter implements Closeable, Flushable {
private static Pattern fsPattern = Pattern.compile(formatSpecifier); private static Pattern fsPattern = Pattern.compile(formatSpecifier);
// Look for format specifiers in the format string. /**
* Finds format specifiers in the format string.
*/
private FormatString[] parse(String s) { private FormatString[] parse(String s) {
ArrayList al = new ArrayList(); ArrayList<FormatString> al = new ArrayList<FormatString>();
Matcher m = fsPattern.matcher(s); Matcher m = fsPattern.matcher(s);
int i = 0; for (int i = 0, len = s.length(); i < len; ) {
while (i < s.length()) {
if (m.find(i)) { if (m.find(i)) {
// Anything between the start of the string and the beginning // Anything between the start of the string and the beginning
// of the format specifier is either fixed text or contains // of the format specifier is either fixed text or contains
// an invalid format string. // an invalid format string.
if (m.start() != i) { if (m.start() != i) {
// Make sure we didn't miss any invalid format specifiers // Make sure we didn't miss any invalid format specifiers
checkText(s.substring(i, m.start())); checkText(s, i, m.start());
// Assume previous characters were fixed text // Assume previous characters were fixed text
al.add(new FixedString(s.substring(i, m.start()))); al.add(new FixedString(s.substring(i, m.start())));
} }
// Expect 6 groups in regular expression al.add(new FormatSpecifier(m));
String[] sa = new String[6];
for (int j = 0; j < m.groupCount(); j++)
{
sa[j] = m.group(j + 1);
// System.out.print(sa[j] + " ");
}
// System.out.println();
al.add(new FormatSpecifier(this, sa));
i = m.end(); i = m.end();
} else { } else {
// No more valid format specifiers. Check for possible invalid // No more valid format specifiers. Check for possible invalid
// format specifiers. // format specifiers.
checkText(s.substring(i)); checkText(s, i, len);
// The rest of the string is fixed text // The rest of the string is fixed text
al.add(new FixedString(s.substring(i))); al.add(new FixedString(s.substring(i)));
break; break;
} }
} }
// FormatString[] fs = new FormatString[al.size()]; return al.toArray(new FormatString[al.size()]);
// for (int j = 0; j < al.size(); j++)
// System.out.println(((FormatString) al.get(j)).toString());
return (FormatString[]) al.toArray(new FormatString[0]);
} }
private void checkText(String s) { private static void checkText(String s, int start, int end) {
int idx; for (int i = start; i < end; i++) {
// If there are any '%' in the given string, we got a bad format // Any '%' found in the region starts an invalid format specifier.
// specifier. if (s.charAt(i) == '%') {
if ((idx = s.indexOf('%')) != -1) { char c = (i == end - 1) ? '%' : s.charAt(i + 1);
char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1)); throw new UnknownFormatConversionException(String.valueOf(c));
throw new UnknownFormatConversionException(String.valueOf(c)); }
} }
} }
...@@ -2562,8 +2552,6 @@ public final class Formatter implements Closeable, Flushable { ...@@ -2562,8 +2552,6 @@ public final class Formatter implements Closeable, Flushable {
private boolean dt = false; private boolean dt = false;
private char c; private char c;
private Formatter formatter;
// cache the line separator // cache the line separator
private String ls; private String ls;
...@@ -2650,21 +2638,22 @@ public final class Formatter implements Closeable, Flushable { ...@@ -2650,21 +2638,22 @@ public final class Formatter implements Closeable, Flushable {
return c; return c;
} }
FormatSpecifier(Formatter formatter, String[] sa) { FormatSpecifier(Matcher m) {
this.formatter = formatter; int idx = 1;
int idx = 0;
index(sa[idx++]); index(m.group(idx++));
flags(sa[idx++]); flags(m.group(idx++));
width(sa[idx++]); width(m.group(idx++));
precision(sa[idx++]); precision(m.group(idx++));
if (sa[idx] != null) { String tT = m.group(idx++);
if (tT != null) {
dt = true; dt = true;
if (sa[idx].equals("T")) if (tT.equals("T"))
f.add(Flags.UPPERCASE); f.add(Flags.UPPERCASE);
} }
conversion(sa[++idx]);
conversion(m.group(idx));
if (dt) if (dt)
checkDateTime(); checkDateTime();
...@@ -2819,9 +2808,9 @@ public final class Formatter implements Closeable, Flushable { ...@@ -2819,9 +2808,9 @@ public final class Formatter implements Closeable, Flushable {
private void printString(Object arg, Locale l) throws IOException { private void printString(Object arg, Locale l) throws IOException {
if (arg instanceof Formattable) { if (arg instanceof Formattable) {
Formatter fmt = formatter; Formatter fmt = Formatter.this;
if (formatter.locale() != l) if (fmt.locale() != l)
fmt = new Formatter(formatter.out(), l); fmt = new Formatter(fmt.out(), l);
((Formattable)arg).formatTo(fmt, f.valueOf(), width, precision); ((Formattable)arg).formatTo(fmt, f.valueOf(), width, precision);
} else { } else {
if (f.contains(Flags.ALTERNATE)) if (f.contains(Flags.ALTERNATE))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册