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:
parent
8e1523d145
commit
1e8ae887c7
@ -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 */
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user