ICU-2374 cache the default NumberFormat and the default DateFormat used when subformats[i].format == NULL; this will improve format() performance in some cases

X-SVN-Rev: 10957
This commit is contained in:
Alan Liu 2003-02-05 00:53:44 +00:00
parent 8e1523d145
commit 1e8ae887c7
2 changed files with 78 additions and 16 deletions

View File

@ -176,6 +176,8 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
argTypes(NULL), argTypes(NULL),
argTypeCount(0), argTypeCount(0),
argTypeCapacity(0), argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL) formatAliases(NULL)
{ {
if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) || if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
@ -196,6 +198,8 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
argTypes(NULL), argTypes(NULL),
argTypeCount(0), argTypeCount(0),
argTypeCapacity(0), argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL) formatAliases(NULL)
{ {
if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) || if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
@ -217,6 +221,8 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
argTypes(NULL), argTypes(NULL),
argTypeCount(0), argTypeCount(0),
argTypeCapacity(0), argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL) formatAliases(NULL)
{ {
if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) || if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
@ -235,6 +241,8 @@ MessageFormat::MessageFormat(const MessageFormat& that)
argTypes(NULL), argTypes(NULL),
argTypeCount(0), argTypeCount(0),
argTypeCapacity(0), argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL) formatAliases(NULL)
{ {
*this = that; *this = that;
@ -251,6 +259,9 @@ MessageFormat::~MessageFormat()
argTypeCount = argTypeCapacity = 0; argTypeCount = argTypeCapacity = 0;
uprv_free(formatAliases); uprv_free(formatAliases);
delete defaultNumberFormat;
delete defaultDateFormat;
} }
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -339,7 +350,7 @@ MessageFormat::operator=(const MessageFormat& that)
Format::operator=(that); Format::operator=(that);
fPattern = that.fPattern; fPattern = that.fPattern;
fLocale = that.fLocale; setLocale(that.fLocale);
int32_t j; int32_t j;
for (j=0; j<subformatCount; ++j) { for (j=0; j<subformatCount; ++j) {
@ -401,6 +412,12 @@ MessageFormat::clone() const
void void
MessageFormat::setLocale(const Locale& theLocale) MessageFormat::setLocale(const Locale& theLocale)
{ {
if (fLocale != theLocale) {
delete defaultNumberFormat;
defaultNumberFormat = NULL;
delete defaultDateFormat;
defaultDateFormat = NULL;
}
fLocale = theLocale; fLocale = theLocale;
} }
@ -862,7 +879,6 @@ MessageFormat::format( const UnicodeString& pattern,
UnicodeString& appendTo, UnicodeString& appendTo,
UErrorCode& success) UErrorCode& success)
{ {
// {sfb} why does this use a local when so many other places use a static?
MessageFormat temp(pattern, success); MessageFormat temp(pattern, success);
FieldPosition ignore(0); FieldPosition ignore(0);
temp.format(arguments, cnt, appendTo, ignore, success); temp.format(arguments, cnt, appendTo, ignore, success);
@ -952,30 +968,23 @@ MessageFormat::format(const Formattable* arguments,
} }
// If the obj data type is a number, use a NumberFormat instance. // If the obj data type is a number, use a NumberFormat instance.
else if ((type == Formattable::kDouble) || (type == Formattable::kLong)) { else if ((type == Formattable::kDouble) || (type == Formattable::kLong)) {
NumberFormat *numTemplate = NULL; const NumberFormat* nf = getDefaultNumberFormat();
numTemplate = NumberFormat::createInstance(fLocale, success); if (nf == NULL) {
if (numTemplate == NULL || U_FAILURE(success)) {
delete numTemplate;
return appendTo; return appendTo;
} }
if (type == Formattable::kDouble) { if (type == Formattable::kDouble) {
numTemplate->format(obj->getDouble(), appendTo); nf->format(obj->getDouble(), appendTo);
} else { } else {
numTemplate->format(obj->getLong(), appendTo); nf->format(obj->getLong(), appendTo);
} }
delete numTemplate;
if (U_FAILURE(success))
return appendTo;
} }
// If the obj data type is a Date instance, use a DateFormat instance. // If the obj data type is a Date instance, use a DateFormat instance.
else if (type == Formattable::kDate) { else if (type == Formattable::kDate) {
DateFormat *dateTemplate = NULL; const DateFormat* df = getDefaultDateFormat();
dateTemplate = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale); if (df == NULL) {
if (dateTemplate == NULL) {
return appendTo; return appendTo;
} }
dateTemplate->format(obj->getDate(), appendTo); df->format(obj->getDate(), appendTo);
delete dateTemplate;
} }
else if (type == Formattable::kString) { else if (type == Formattable::kString) {
appendTo += obj->getString(); appendTo += obj->getString();
@ -1331,6 +1340,41 @@ MessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) con
return temp; return temp;
} }
/**
* Return the default number format. Used to format a numeric
* argument when subformats[i].format is NULL. Returns NULL
* on failure.
*
* Semantically const but may modify *this.
*/
const NumberFormat* MessageFormat::getDefaultNumberFormat() const {
if (defaultNumberFormat == NULL) {
MessageFormat* t = (MessageFormat*) this;
UErrorCode ec = U_ZERO_ERROR;
t->defaultNumberFormat = NumberFormat::createInstance(fLocale, ec);
if (U_FAILURE(ec)) {
delete t->defaultNumberFormat;
t->defaultNumberFormat = NULL;
}
}
return defaultNumberFormat;
}
/**
* Return the default date format. Used to format a date
* argument when subformats[i].format is NULL. Returns NULL
* on failure.
*
* Semantically const but may modify *this.
*/
const DateFormat* MessageFormat::getDefaultDateFormat() const {
if (defaultDateFormat == NULL) {
MessageFormat* t = (MessageFormat*) this;
t->defaultDateFormat = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale);
}
return defaultDateFormat;
}
U_NAMESPACE_END U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */ #endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -31,6 +31,7 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
class NumberFormat; class NumberFormat;
class DateFormat;
/** /**
* A MessageFormat produces concatenated messages in a * A MessageFormat produces concatenated messages in a
@ -663,6 +664,23 @@ private:
UBool allocateSubformats(int32_t capacity); UBool allocateSubformats(int32_t capacity);
UBool allocateArgTypes(int32_t capacity); UBool allocateArgTypes(int32_t capacity);
/**
* Default Format objects used when no format is specified and a
* numeric or date argument is formatted. These are volatile
* cache objects maintained only for performance. They do not
* participate in operator=(), copy constructor(), nor
* operator==().
*/
NumberFormat* defaultNumberFormat;
DateFormat* defaultDateFormat;
/**
* Method to retrieve default formats (or NULL on failure).
* These are semantically const, but may modify *this.
*/
const NumberFormat* getDefaultNumberFormat() const;
const DateFormat* getDefaultDateFormat() const;
/** /**
* Finds the word s, in the keyword list and returns the located index. * Finds the word s, in the keyword list and returns the located index.
* @param s the keyword to be searched for. * @param s the keyword to be searched for.