I have updated the patch and add it to jira so that DateFormatSymbols can
follow the cimpatibility and write a testcase for its serialization:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.DateFormatSymbols;
import java.util.Arrays;
import junit.framework.TestCase;
public class TestDateFormatSymbolsSerialization extends TestCase {
private ByteArrayOutputStream bao;
private ObjectOutputStream oos;
private ObjectInputStream ois;
public TestDateFormatSymbolsSerialization(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void test_Serialization_DateFormatSymbols() throws IOException,
ClassNotFoundException {
DateFormatSymbols dfs = new DateFormatSymbols();
String[][] zoneStrings = dfs.getZoneStrings();
oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
oos.writeObject(dfs);
ois = new ObjectInputStream(new
ByteArrayInputStream(bao.toByteArray()));
DateFormatSymbols result = (DateFormatSymbols) ois.readObject();
String[][] rsZoneStrings = result.getZoneStrings();
if (zoneStrings.length != rsZoneStrings.length) {
fail("zoneStrings and rsZoneStrings is not equal");
}
for (int i = 0; i < zoneStrings.length; i++) {
if (!Arrays.equals(zoneStrings[i], rsZoneStrings[i])) {
fail("zoneStrings and rsZoneStrings is not equal");
}
}
}
}
2009/2/18 Tony Wu <[email protected]>
> Great! I think it does help us on start up time.
>
> But your patch breaks the serialization compatibility. I suggest to
> make the icuSymbols transient and override the writeObject to make
> sure the zoneStrings has been initialized before writing it out. And I
> think it is not necessay to maintain the local var with the same name
> anymore.
>
> On Wed, Feb 18, 2009 at 1:43 PM, Deven You <[email protected]> wrote:
> > Hi,
> > I have raised a jira HARMONY-6095 for improving
> java.text.DateFormatSymbols
> > performance. I found DateFormatSymbols(Locale) will invoke
> > com.ibm.icu.text.DateFormatSymbols.getZoneStrings() which can take
> > significant time but rarely used in real world applications. So I delay
> this
> > call until it really be used. it seems the performance of
> > DateFormatSymbols(Locale) can be greatly improved.*
> > *the testcase is:
> >
> > import java.text.DateFormatSymbols;
> > import java.util.Locale;
> >
> > public class TestDateFormatSymbols {
> >
> > /**
> > * @param args
> > */
> > public static void main(String[] args) {
> > long time = System.currentTimeMillis();
> > DateFormatSymbols dfs = new
> DateFormatSymbols(Locale.getDefault());
> > time = System.currentTimeMillis() - time;
> >
> > System.out.println("the total time is " + time + " ms!");
> > }
> >
> > }
> >
> > I have tested on Intel(R) Core(TM)2 Duo Cpu 2.4GHZ, 2.98GB Memory
> machine,
> > the result is as below:
> > Harmony patch before: 1125 ms
> > Harmony patched: 78 ms
> >
>
>
>
> --
> Tony Wu
> China Software Development Lab, IBM
>
Index: modules/text/src/main/java/java/text/DateFormatSymbols.java
===================================================================
--- modules/text/src/main/java/java/text/DateFormatSymbols.java (revision 745375)
+++ modules/text/src/main/java/java/text/DateFormatSymbols.java (working copy)
@@ -17,6 +17,8 @@
package java.text;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Locale;
@@ -35,6 +37,8 @@
String[][] zoneStrings;
+ transient private com.ibm.icu.text.DateFormatSymbols icuSymbols;
+
/**
* Constructs a new DateFormatSymbols containing the symbols for the default
* Locale.
@@ -51,8 +55,7 @@
* the Locale
*/
public DateFormatSymbols(Locale locale) {
- com.ibm.icu.text.DateFormatSymbols icuSymbols = new com.ibm.icu.text.DateFormatSymbols(locale);
-
+ icuSymbols = new com.ibm.icu.text.DateFormatSymbols(locale);
localPatternChars = icuSymbols.getLocalPatternChars();
ampms = icuSymbols.getAmPmStrings();
eras = icuSymbols.getEras();
@@ -60,9 +63,16 @@
shortMonths = icuSymbols.getShortMonths();
shortWeekdays = icuSymbols.getShortWeekdays();
weekdays = icuSymbols.getWeekdays();
- zoneStrings = icuSymbols.getZoneStrings();
}
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ if (zoneStrings == null) {
+ zoneStrings = icuSymbols.getZoneStrings();
+ }
+ oos.defaultWriteObject();
+ }
+
/**
* Answers a new DateFormatSymbols with the same symbols as this
* DateFormatSymbols.
@@ -73,6 +83,9 @@
*/
@Override
public Object clone() {
+ if (zoneStrings == null) {
+ zoneStrings = icuSymbols.getZoneStrings();
+ }
try {
DateFormatSymbols symbols = (DateFormatSymbols) super.clone();
symbols.ampms = ampms.clone();
@@ -111,7 +124,15 @@
if (!(object instanceof DateFormatSymbols)) {
return false;
}
+ if (zoneStrings == null) {
+ zoneStrings = icuSymbols.getZoneStrings();
+ }
+
DateFormatSymbols obj = (DateFormatSymbols) object;
+
+ if (obj.zoneStrings == null) {
+ obj.zoneStrings = obj.icuSymbols.getZoneStrings();
+ }
if (!localPatternChars.equals(obj.localPatternChars)) {
return false;
}
@@ -234,6 +255,9 @@
* @return a two-dimensional array of String
*/
public String[][] getZoneStrings() {
+ if (zoneStrings == null) {
+ zoneStrings = icuSymbols.getZoneStrings();
+ }
String[][] clone = new String[zoneStrings.length][];
for (int i = zoneStrings.length; --i >= 0;) {
clone[i] = zoneStrings[i].clone();
@@ -251,6 +275,9 @@
*/
@Override
public int hashCode() {
+ if (zoneStrings == null) {
+ zoneStrings = icuSymbols.getZoneStrings();
+ }
int hashCode;
hashCode = localPatternChars.hashCode();
for (String element : ampms) {
Index: modules/text/src/main/java/java/text/SimpleDateFormat.java
===================================================================
--- modules/text/src/main/java/java/text/SimpleDateFormat.java (版本 743965)
+++ modules/text/src/main/java/java/text/SimpleDateFormat.java (工作副本)
@@ -576,7 +576,7 @@
if (generalTimezone) {
String id = calendar.getTimeZone().getID();
- String[][] zones = formatData.zoneStrings;
+ String[][] zones = formatData.getZoneStrings();
String[] zone = null;
for (String[] element : zones) {
if (id.equals(element[0])) {