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),
argTypeCount(0),
argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL)
{
if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
@ -196,6 +198,8 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
argTypes(NULL),
argTypeCount(0),
argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL)
{
if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
@ -217,6 +221,8 @@ MessageFormat::MessageFormat(const UnicodeString& pattern,
argTypes(NULL),
argTypeCount(0),
argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL)
{
if (!allocateSubformats(DEFAULT_INITIAL_CAPACITY) ||
@ -235,6 +241,8 @@ MessageFormat::MessageFormat(const MessageFormat& that)
argTypes(NULL),
argTypeCount(0),
argTypeCapacity(0),
defaultNumberFormat(NULL),
defaultDateFormat(NULL),
formatAliases(NULL)
{
*this = that;
@ -251,6 +259,9 @@ MessageFormat::~MessageFormat()
argTypeCount = argTypeCapacity = 0;
uprv_free(formatAliases);
delete defaultNumberFormat;
delete defaultDateFormat;
}
//--------------------------------------------------------------------
@ -339,7 +350,7 @@ MessageFormat::operator=(const MessageFormat& that)
Format::operator=(that);
fPattern = that.fPattern;
fLocale = that.fLocale;
setLocale(that.fLocale);
int32_t j;
for (j=0; j<subformatCount; ++j) {
@ -401,6 +412,12 @@ MessageFormat::clone() const
void
MessageFormat::setLocale(const Locale& theLocale)
{
if (fLocale != theLocale) {
delete defaultNumberFormat;
defaultNumberFormat = NULL;
delete defaultDateFormat;
defaultDateFormat = NULL;
}
fLocale = theLocale;
}
@ -862,7 +879,6 @@ MessageFormat::format( const UnicodeString& pattern,
UnicodeString& appendTo,
UErrorCode& success)
{
// {sfb} why does this use a local when so many other places use a static?
MessageFormat temp(pattern, success);
FieldPosition ignore(0);
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.
else if ((type == Formattable::kDouble) || (type == Formattable::kLong)) {
NumberFormat *numTemplate = NULL;
numTemplate = NumberFormat::createInstance(fLocale, success);
if (numTemplate == NULL || U_FAILURE(success)) {
delete numTemplate;
const NumberFormat* nf = getDefaultNumberFormat();
if (nf == NULL) {
return appendTo;
}
if (type == Formattable::kDouble) {
numTemplate->format(obj->getDouble(), appendTo);
nf->format(obj->getDouble(), appendTo);
} 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.
else if (type == Formattable::kDate) {
DateFormat *dateTemplate = NULL;
dateTemplate = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale);
if (dateTemplate == NULL) {
const DateFormat* df = getDefaultDateFormat();
if (df == NULL) {
return appendTo;
}
dateTemplate->format(obj->getDate(), appendTo);
delete dateTemplate;
df->format(obj->getDate(), appendTo);
}
else if (type == Formattable::kString) {
appendTo += obj->getString();
@ -1331,6 +1340,41 @@ MessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) con
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
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -31,6 +31,7 @@
U_NAMESPACE_BEGIN
class NumberFormat;
class DateFormat;
/**
* A MessageFormat produces concatenated messages in a
@ -663,6 +664,23 @@ private:
UBool allocateSubformats(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.
* @param s the keyword to be searched for.