Author: etnu
Date: Fri Dec 5 12:34:06 2008
New Revision: 723857
URL: http://svn.apache.org/viewvc?rev=723857&view=rev
Log:
Changed unicode escaping code to a model based on that found in
java.util.Properties on Henning's recommendation. This outperforms the larger
lookup table in the original benchmark by about 10-15%, presumably because of
better caching behavior with the smaller lookup table (~32 bytes instead of
~64K). This gain held true on both Sun and OpenJDK 6 using several combinations
of GC flags. The code is a bit more readable in my opinion as well, so overall
it seems to be the current best technique for this particular part of the
serializer.
At this point JsonSerializer doesn't show any obvious shortcomings, though it
only holds a small advantage over the json.org implementation on very large
data sets, such as 1MB of data where the size of the average entry is much
higher than 256 bytes. 256 bytes was arrived as a good default assumption for
entry size based on the average size showing up during profiling of a prod
setup. I suspect that further tuning of this isn't going to yield much of a net
gain though.
Future patches should probably start swapping out the existing object to
JSONObject to string conversions with calls to
JsonSerializer.serialize(object).
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java?rev=723857&r1=723856&r2=723857&view=diff
==============================================================================
---
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
(original)
+++
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonSerializer.java
Fri Dec 5 12:34:06 2008
@@ -40,20 +40,12 @@
// Multiplier to use for allocating the buffer.
private static final int BASE_MULTIPLIER = 256;
- private static final String[] UNICODE_TABLE = createUnicodeTable();
+ private static final char[] HEX_DIGITS = {
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+ };
private JsonSerializer() {}
- private static String[] createUnicodeTable() {
- String[] table = new String['\u2100'];
- for (char c = 0; c < table.length; ++c) {
- String hex = Integer.toHexString(c);
- table[c] = "u" + (("000" + hex).substring(hex.length() - 1));
- }
- // Other characters can be sent with plain UTF-8 encoding.
- return table;
- }
-
/**
* Serialize a JSONObject. Does not guard against cyclical references.
*/
@@ -320,9 +312,18 @@
// 2. for (int i = 0; i < 4 - value.length(); ++i) {
buf.append('0'); }
// 3. buf.append(value)
//
- // Of these, the second proved fastest. The current
implementation performs slightly
- // faster than the second in the benchmark found in
JsonSerializerTest.
- buf.append(UNICODE_TABLE[current]);
+ // Method 4 (Sun conversion from java.util.Properties)
+ // 1. Append '\'
+ // 2. Append 'u'
+ // 3. Append each of 4 octets by indexing into a hex array.
+ //
+ // Method 5
+ // Index into a single lookup table of all relevant lookup
values.
+ buf.append('u');
+ buf.append(HEX_DIGITS[(current >> 12) & 0xF]);
+ buf.append(HEX_DIGITS[(current >> 8) & 0xF]);
+ buf.append(HEX_DIGITS[(current >> 4) & 0xF]);
+ buf.append(HEX_DIGITS[current & 0xF]);
}
} else {
buf.append(current);