mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-5316 Increase the performance of sprintf/sscanf
X-SVN-Rev: 20050
This commit is contained in:
parent
13a2bd3fbb
commit
2a806e34dc
6 changed files with 153 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
|||
#******************************************************************************
|
||||
#
|
||||
# Copyright (C) 1999-2005, International Business Machines
|
||||
# Copyright (C) 1999-2006, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#
|
||||
#******************************************************************************
|
||||
|
@ -61,7 +61,7 @@ LIBS = $(LIBICUUC) $(LIBICUI18N) $(DEFAULT_LIBS)
|
|||
|
||||
OBJECTS = locbund.o ufile.o ufmt_cmn.o uprintf.o uprntf_p.o \
|
||||
uscanf.o uscanf_p.o ustdio.o sprintf.o sscanf.o \
|
||||
ustream.o
|
||||
ustream.o ucln_io.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS = $(srcdir)/unicode/*.h
|
||||
|
|
|
@ -160,6 +160,9 @@
|
|||
<File
|
||||
RelativePath=".\sscanf.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ucln_io.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ufile.c">
|
||||
</File>
|
||||
|
@ -203,6 +206,9 @@
|
|||
<File
|
||||
RelativePath=".\locbund.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ucln_io.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ufile.h">
|
||||
</File>
|
||||
|
|
|
@ -24,9 +24,51 @@
|
|||
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "ucln_io.h"
|
||||
#include "umutex.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/uloc.h"
|
||||
|
||||
static UBool isFormatsInitialized = FALSE;
|
||||
static UNumberFormat *gPosixNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT];
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV locbund_cleanup(void) {
|
||||
int32_t style;
|
||||
for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) {
|
||||
unum_close(gPosixNumberFormat[style]);
|
||||
gPosixNumberFormat[style] = NULL;
|
||||
}
|
||||
isFormatsInitialized = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
|
||||
static U_INLINE UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
|
||||
if (result->fNumberFormat[style-1] == NULL) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UBool needsInit;
|
||||
|
||||
UMTX_CHECK(NULL, gPosixNumberFormat[style-1] == NULL, needsInit);
|
||||
if (needsInit) {
|
||||
UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status);
|
||||
|
||||
/* Cache upon first request. */
|
||||
if (U_SUCCESS(status)) {
|
||||
umtx_lock(NULL);
|
||||
gPosixNumberFormat[style-1] = formatAlias;
|
||||
ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the needed formatter. */
|
||||
result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
|
||||
}
|
||||
return result->fNumberFormat[style-1];
|
||||
}
|
||||
|
||||
ULocaleBundle*
|
||||
u_locbund_init(ULocaleBundle *result, const char *loc)
|
||||
{
|
||||
|
@ -49,6 +91,8 @@ u_locbund_init(ULocaleBundle *result, const char *loc)
|
|||
|
||||
uprv_strcpy(result->fLocale, loc);
|
||||
|
||||
result->isInvariantLocale = uprv_strcmp(result->fLocale, "en_US_POSIX") == 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -121,14 +165,19 @@ u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style)
|
|||
if (style >= UNUM_IGNORE) {
|
||||
formatAlias = bundle->fNumberFormat[style-1];
|
||||
if (formatAlias == NULL) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
unum_close(formatAlias);
|
||||
formatAlias = NULL;
|
||||
if (bundle->isInvariantLocale) {
|
||||
formatAlias = copyInvariantFormatter(bundle, style);
|
||||
}
|
||||
else {
|
||||
bundle->fNumberFormat[style-1] = formatAlias;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
unum_close(formatAlias);
|
||||
formatAlias = NULL;
|
||||
}
|
||||
else {
|
||||
bundle->fNumberFormat[style-1] = formatAlias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Copyright (C) 1998-2006s, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -31,6 +31,7 @@ typedef struct ULocaleBundle {
|
|||
char *fLocale;
|
||||
|
||||
UNumberFormat *fNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT];
|
||||
UBool isInvariantLocale;
|
||||
} ULocaleBundle;
|
||||
|
||||
|
||||
|
|
51
icu4c/source/io/ucln_io.c
Normal file
51
icu4c/source/io/ucln_io.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* *
|
||||
* Copyright (C) 2001-2006, International Business Machines *
|
||||
* Corporation and others. All Rights Reserved. *
|
||||
* *
|
||||
******************************************************************************
|
||||
* file name: ucln_io.c
|
||||
* encoding: US-ASCII
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
* created on: 2006August11
|
||||
* created by: George Rhoten
|
||||
*/
|
||||
|
||||
#include "ucln.h"
|
||||
#include "ucln_io.h"
|
||||
#include "umutex.h"
|
||||
#include "uassert.h"
|
||||
|
||||
/* Leave this copyright notice here! It needs to go somewhere in this library. */
|
||||
static const char copyright[] = U_COPYRIGHT_STRING;
|
||||
|
||||
static cleanupFunc *gCleanupFunctions[UCLN_IO_COUNT];
|
||||
|
||||
static UBool io_cleanup(void)
|
||||
{
|
||||
ECleanupIOType libType;
|
||||
|
||||
for (libType = UCLN_IO_START+1; libType<UCLN_IO_COUNT; libType++) {
|
||||
if (gCleanupFunctions[libType])
|
||||
{
|
||||
gCleanupFunctions[libType]();
|
||||
gCleanupFunctions[libType] = NULL;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ucln_io_registerCleanup(ECleanupIOType type,
|
||||
cleanupFunc *func)
|
||||
{
|
||||
U_ASSERT(UCLN_IO_START < type && type < UCLN_IO_COUNT);
|
||||
ucln_registerCleanup(UCLN_IO, io_cleanup);
|
||||
if (UCLN_IO_START < type && type < UCLN_IO_COUNT)
|
||||
{
|
||||
gCleanupFunctions[type] = func;
|
||||
}
|
||||
}
|
||||
|
37
icu4c/source/io/ucln_io.h
Normal file
37
icu4c/source/io/ucln_io.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* *
|
||||
* Copyright (C) 2001-2006, International Business Machines *
|
||||
* Corporation and others. All Rights Reserved. *
|
||||
* *
|
||||
******************************************************************************
|
||||
* file name: ucln_io.h
|
||||
* encoding: US-ASCII
|
||||
* tab size: 8 (not used)
|
||||
* indentation:4
|
||||
*
|
||||
* created on: 2006August11
|
||||
* created by: George Rhoten
|
||||
*/
|
||||
|
||||
#ifndef __UCLN_IO_H__
|
||||
#define __UCLN_IO_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "ucln.h"
|
||||
|
||||
/*
|
||||
Please keep the order of enums declared in same order
|
||||
as the functions are suppose to be called. */
|
||||
typedef enum ECleanupIOType {
|
||||
UCLN_IO_START = -1,
|
||||
UCLN_IO_LOCBUND,
|
||||
UCLN_IO_COUNT /* This must be last */
|
||||
} ECleanupIOType;
|
||||
|
||||
/* Main library cleanup registration function. */
|
||||
/* See common/ucln.h for details on adding a cleanup function. */
|
||||
U_CFUNC void U_EXPORT2 ucln_io_registerCleanup(ECleanupIOType type,
|
||||
cleanupFunc *func);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue