Skip to content

Commit f1b138f

Browse files
committed
Allocations optimization
See pull request Allocations optimization for converters quickfix-j#34
1 parent 6cba620 commit f1b138f

File tree

1 file changed

+41
-14
lines changed

1 file changed

+41
-14
lines changed

quickfixj-core/src/main/java/quickfix/field/converter/UtcTimestampConverter.java

+41-14
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,20 @@
3333
* and a time.
3434
*/
3535
public class UtcTimestampConverter extends AbstractDateTimeConverter {
36-
private static final ThreadLocal<UtcTimestampConverter> utcTimestampConverter = new ThreadLocal<UtcTimestampConverter>();
37-
private final DateFormat utcTimestampFormat = createDateFormat("yyyyMMdd-HH:mm:ss");
38-
private final DateFormat utcTimestampFormatMillis = createDateFormat("yyyyMMdd-HH:mm:ss.SSS");
36+
37+
protected static final class Context {
38+
private final DateFormat utcTimestampFormat = createDateFormat("yyyyMMdd-HH:mm:ss");
39+
private final DateFormat utcTimestampFormatMillis = createDateFormat("yyyyMMdd-HH:mm:ss.SSS");
40+
private final StringBuffer buffer = new StringBuffer(128);
41+
}
42+
43+
private static final ThreadLocal<Context> utcTimestampConverter = new ThreadLocal<Context>() {
44+
@Override
45+
protected Context initialValue() {
46+
return new Context();
47+
}
48+
};
49+
3950
private final static ConcurrentHashMap<String, Long> dateCache = new ConcurrentHashMap<String, Long>();
4051

4152
/**
@@ -46,16 +57,32 @@ public class UtcTimestampConverter extends AbstractDateTimeConverter {
4657
* @return the formatted timestamp
4758
*/
4859
public static String convert(Date d, boolean includeMilliseconds) {
49-
return getFormatter(includeMilliseconds).format(d);
60+
Context context = utcTimestampConverter.get();
61+
try {
62+
(includeMilliseconds ? context.utcTimestampFormatMillis : context.utcTimestampFormat)
63+
.format(d, context.buffer, DontCareFieldPosition.INSTANCE);
64+
return context.buffer.toString();
65+
} finally {
66+
context.buffer.setLength(0);
67+
}
5068
}
5169

52-
private static DateFormat getFormatter(boolean includeMillis) {
53-
UtcTimestampConverter converter = utcTimestampConverter.get();
54-
if (converter == null) {
55-
converter = new UtcTimestampConverter();
56-
utcTimestampConverter.set(converter);
70+
/**
71+
* Convert a timestamp (represented as a Date) to a String.
72+
*
73+
* @param d the date to convert
74+
* @param includeMilliseconds controls whether milliseconds are included in the result
75+
* @param stringBuilder the out buffer to hold the formatted timestamp
76+
*/
77+
public static void convert(Date d, StringBuilder stringBuilder, boolean includeMilliseconds) {
78+
Context context = utcTimestampConverter.get();
79+
try {
80+
(includeMilliseconds ? context.utcTimestampFormatMillis : context.utcTimestampFormat)
81+
.format(d, context.buffer, DontCareFieldPosition.INSTANCE);
82+
stringBuilder.append(context.buffer);
83+
} finally {
84+
context.buffer.setLength(0);
5785
}
58-
return includeMillis ? converter.utcTimestampFormatMillis : converter.utcTimestampFormat;
5986
}
6087

6188
//
@@ -73,11 +100,11 @@ private static DateFormat getFormatter(boolean includeMillis) {
73100
*/
74101
public static Date convert(String value) throws FieldConvertError {
75102
verifyFormat(value);
76-
long timeOffset = (parseLong(value.substring(9, 11)) * 3600000L)
77-
+ (parseLong(value.substring(12, 14)) * 60000L)
78-
+ (parseLong(value.substring(15, 17)) * 1000L);
103+
long timeOffset = (parseLong(value, 9, 11) * 3600000L)
104+
+ (parseLong(value, 12, 14) * 60000L)
105+
+ (parseLong(value, 15, 17) * 1000L);
79106
if (value.length() == 21) {
80-
timeOffset += parseLong(value.substring(18, 21));
107+
timeOffset += parseLong(value, 18, 21);
81108
}
82109
return new Date(getMillisForDay(value) + timeOffset);
83110
}

0 commit comments

Comments
 (0)