summaryrefslogtreecommitdiffstats
path: root/icu/src/main
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2010-01-13 23:14:56 -0800
committerElliott Hughes <enh@google.com>2010-01-14 12:50:53 -0800
commite1e5e8e60af12f145c4dd0395e30069665f97529 (patch)
tree191a722e9ccb999bf9eec8d162abc540f409fa8e /icu/src/main
parentb64c406bd2becd117d88cef3d90d84243d6016af (diff)
downloadlibcore-e1e5e8e60af12f145c4dd0395e30069665f97529.zip
libcore-e1e5e8e60af12f145c4dd0395e30069665f97529.tar.gz
libcore-e1e5e8e60af12f145c4dd0395e30069665f97529.tar.bz2
Fix Date.toString.
Date.toString was using the TimeZone id ("America/Los_Angeles") rather than the time zone short name ("PDT" or "PST", depending on time of year). The naive fix made things 5x slower, so I improved Resources.getDisplayTimeZone so the fixed Date.toString is only 2x slower. This could be improved further with a faster getDisplayTimeZone. I hoped to replace the body of Date.toString with a call to SimpleDateFormat, but that turns out to be 40x slower. This patch also optimizes SimpleDateFormat to bring the gap down to 8x by using Resources.getDisplayTimeZone instead of asking for all the strings. (Note that these improvements refer to the hopefully common case of localized strings for the default locale. If you have the misfortune to need strings for other locales, the new code will be more like 600x faster. At 0.5s a call on the fastest current hardware, I hope no-one's actually doing that. Dalvik Explorer -- available on the Market -- needs to do it when generating summary reports, and it is indeed ridiculously slow. It uses two SimpleDateFormat objects per locale, so it takes 1s per locale, for about 60 locales. I've tested Dalvik Explorer with this patch, and it does fix that pathological behavior.) Also fix a bug I introduced in https://android-git.corp.google.com/g/36242 that meant that our zone names String[][] contained incorrect values (accidentally concatenating each successive value in a row), found by existing tests now we use more of those values. Also replace a couple of "new Integer" calls with Integer.valueOf for a modest speedup. Also factor out some duplication. Bug: http://code.google.com/p/android/issues/detail?id=6013
Diffstat (limited to 'icu/src/main')
-rw-r--r--icu/src/main/java/com/ibm/icu4jni/util/Resources.java31
-rw-r--r--icu/src/main/native/ResourceInterface.cpp19
2 files changed, 36 insertions, 14 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
index f1c50e3..cbad9a5 100644
--- a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
+++ b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
@@ -29,7 +29,7 @@ import java.util.logging.Logger;
/**
* Makes ICU data accessible to Java.
*
- * TODO: finish removing the expensive ResourceBundle nonsense and rename this class.
+ * TODO: move the LocaleData stuff into LocaleData and rename this class.
*/
public class Resources {
// A cache for the locale-specific data.
@@ -152,13 +152,34 @@ public class Resources {
* Returns the display name for the given time zone using the given locale.
*
* @param id The time zone ID, for example "Europe/Berlin"
- * @param isDST Indicates whether daylight savings is in use
+ * @param daylight Indicates whether daylight savings is in use
* @param style The style, 0 for long, 1 for short
* @param locale The locale name, for example "en_US".
* @return The desired display name
*/
- public static String getDisplayTimeZone(String id, boolean isDST, int style, String locale) {
- return getDisplayTimeZoneNative(id, isDST, style, locale);
+ public static String getDisplayTimeZone(String id, boolean daylight, int style, String locale) {
+ // If we already have the strings, linear search through them is 10x quicker than
+ // calling ICU for just the one we want.
+ if (DefaultTimeZones.locale.equals(locale)) {
+ String result = lookupDisplayTimeZone(DefaultTimeZones.names, id, daylight, style);
+ if (result != null) {
+ return result;
+ }
+ }
+ return getDisplayTimeZoneNative(id, daylight, style, locale);
+ }
+
+ public static String lookupDisplayTimeZone(String[][] zoneStrings, String id, boolean daylight, int style) {
+ for (String[] row : zoneStrings) {
+ if (row[0].equals(id)) {
+ if (daylight) {
+ return (style == TimeZone.LONG) ? row[3] : row[4];
+ } else {
+ return (style == TimeZone.LONG) ? row[1] : row[2];
+ }
+ }
+ }
+ return null;
}
/**
@@ -238,7 +259,7 @@ public class Resources {
* "Europe/Berlin". The other columns then hold for each row the
* four time zone names with and without daylight savings and in
* long and short format. It's exactly the array layout required by
- * the TomeZone class.
+ * the TimeZone class.
*/
public static String[][] getDisplayTimeZones(String locale) {
String defaultLocale = Locale.getDefault().toString();
diff --git a/icu/src/main/native/ResourceInterface.cpp b/icu/src/main/native/ResourceInterface.cpp
index 151b23e..3cb4224 100644
--- a/icu/src/main/native/ResourceInterface.cpp
+++ b/icu/src/main/native/ResourceInterface.cpp
@@ -252,6 +252,12 @@ static TimeZone* timeZoneFromId(JNIEnv* env, jstring id) {
return TimeZone::createTimeZone(zoneID);
}
+static jstring formatDate(JNIEnv* env, const SimpleDateFormat& fmt, const UDate& when) {
+ UnicodeString str;
+ fmt.format(when, str);
+ return env->NewString(str.getBuffer(), str.length());
+}
+
static void getTimeZonesNative(JNIEnv* env, jclass clazz,
jobjectArray outerArray, jstring locale) {
@@ -304,24 +310,19 @@ static void getTimeZonesNative(JNIEnv* env, jclass clazz,
daylightSavingDate = date2;
}
- UnicodeString str;
- shortFormat.format(daylightSavingDate, str);
- jstring content = env->NewString(str.getBuffer(), str.length());
+ jstring content = formatDate(env, shortFormat, daylightSavingDate);
env->SetObjectArrayElement(shortDlTimeArray, i, content);
env->DeleteLocalRef(content);
- shortFormat.format(standardDate, str);
- content = env->NewString(str.getBuffer(), str.length());
+ content = formatDate(env, shortFormat, standardDate);
env->SetObjectArrayElement(shortStdTimeArray, i, content);
env->DeleteLocalRef(content);
- longFormat.format(daylightSavingDate, str);
- content = env->NewString(str.getBuffer(), str.length());
+ content = formatDate(env, longFormat, daylightSavingDate);
env->SetObjectArrayElement(longDlTimeArray, i, content);
env->DeleteLocalRef(content);
- longFormat.format(standardDate, str);
- content = env->NewString(str.getBuffer(), str.length());
+ content = formatDate(env, longFormat, standardDate);
env->SetObjectArrayElement(longStdTimeArray, i, content);
env->DeleteLocalRef(content);