Skip to content

Commit

Permalink
Improve serialization performance
Browse files Browse the repository at this point in the history
1. Change properties serializer collection from Map to array
2. Do not escape properties name if not needed
  • Loading branch information
nmorel committed Jan 18, 2015
1 parent da10a8b commit 755d5c9
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@
*/
public class BenchmarkView extends Composite implements Editor<Criteria> {

public static interface PersonMapper extends ObjectMapper<List<Person>> {}

interface CriteriaDriver extends SimpleBeanEditorDriver<Criteria, BenchmarkView> {}

interface BenchmarkViewUiBinder extends UiBinder<Widget, BenchmarkView> {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*/
public abstract class AbstractBeanJsonSerializer<T> extends JsonSerializer<T> implements InternalSerializer<T> {

protected final Map<String, BeanPropertySerializer<T, ?>> serializers;
protected final BeanPropertySerializer[] serializers;

private final Map<Class, SubtypeSerializer> subtypeClassToSerializer;

Expand All @@ -59,8 +59,8 @@ protected AbstractBeanJsonSerializer() {
* Initialize the {@link Map} containing the property serializers. Returns an empty map if there are no properties to
* serialize.
*/
protected Map<String, BeanPropertySerializer<T, ?>> initSerializers() {
return Collections.emptyMap();
protected BeanPropertySerializer[] initSerializers() {
return new BeanPropertySerializer[0];
}

/**
Expand Down Expand Up @@ -95,8 +95,7 @@ protected AnyGetterPropertySerializer<T> initAnyGetterPropertySerializer() {

@Override
public void doSerialize( JsonWriter writer, @Nonnull T value, JsonSerializationContext ctx, JsonSerializerParameters params ) {
getSerializer( writer, value, ctx )
.serializeInternally( writer, value, ctx, params, defaultIdentityInfo, defaultTypeInfo, serializers );
getSerializer( writer, value, ctx ).serializeInternally( writer, value, ctx, params, defaultIdentityInfo, defaultTypeInfo );
}

private InternalSerializer<T> getSerializer( JsonWriter writer, T value, JsonSerializationContext ctx ) {
Expand All @@ -115,8 +114,7 @@ private InternalSerializer<T> getSerializer( JsonWriter writer, T value, JsonSer
}

public void serializeInternally( JsonWriter writer, T value, JsonSerializationContext ctx, JsonSerializerParameters params,
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo,
Map<String, BeanPropertySerializer<T, ?>> serializers ) {
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo ) {

// Processing the parameters. We fallback to default if parameter is not present.
final IdentitySerializationInfo identityInfo = null == params.getIdentityInfo() ? defaultIdentityInfo : params.getIdentityInfo();
Expand All @@ -133,12 +131,7 @@ public void serializeInternally( JsonWriter writer, T value, JsonSerializationCo
return;
}

if ( identityInfo.isProperty() ) {
BeanPropertySerializer<T, ?> propertySerializer = serializers.get( identityInfo.getPropertyName() );
idWriter = new ObjectIdSerializer( propertySerializer.getValue( value, ctx ), propertySerializer.getSerializer() );
} else {
idWriter = identityInfo.getObjectId( value, ctx );
}
idWriter = identityInfo.getObjectId( value, ctx );
if ( identityInfo.isAlwaysAsId() ) {
idWriter.serializeId( writer, ctx );
return;
Expand Down Expand Up @@ -227,11 +220,11 @@ protected void serializeObject( JsonWriter writer, T value, JsonSerializationCon
idWriter.serializeId( writer, ctx );
}

for ( Map.Entry<String, BeanPropertySerializer<T, ?>> entry : serializers.entrySet() ) {
if ( (null == identityInfo || !identityInfo.isProperty() || !identityInfo.getPropertyName().equals( entry
.getKey() )) && !ignoredProperties.contains( entry.getKey() ) ) {
writer.name( entry.getKey() );
entry.getValue().serialize( writer, value, ctx );
for ( BeanPropertySerializer<T, ?> propertySerializer : serializers ) {
if ( (null == identityInfo || !identityInfo.isProperty() || !identityInfo.getPropertyName().equals( propertySerializer
.getPropertyName() )) && !ignoredProperties.contains( propertySerializer.getPropertyName() ) ) {
propertySerializer.serializePropertyName( writer, value, ctx );
propertySerializer.serialize( writer, value, ctx );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public abstract class AnyGetterPropertySerializer<T> extends BeanPropertySeriali

protected abstract MapJsonSerializer newSerializer();

public AnyGetterPropertySerializer() {
super( null );
}

public void serializePropertyName( JsonWriter writer, T bean, JsonSerializationContext ctx ) {
// no-op
}

/**
* Serializes the property defined for this instance.
*
Expand All @@ -40,7 +48,7 @@ public abstract class AnyGetterPropertySerializer<T> extends BeanPropertySeriali
*/
public void serialize( JsonWriter writer, T bean, JsonSerializationContext ctx ) {
Map map = getValue( bean, ctx );
if(null != map) {
if ( null != map ) {
((MapJsonSerializer) getSerializer()).serializeValues( writer, map, ctx, getParameters() );
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@
*/
public abstract class BeanPropertySerializer<T, V> extends HasSerializer<V, JsonSerializer<V>> {

protected final String propertyName;

private JsonSerializerParameters parameters;

protected BeanPropertySerializer( String propertyName ) {
this.propertyName = propertyName;
}

protected JsonSerializerParameters getParameters() {
if ( null == parameters ) {
parameters = newParameters();
Expand All @@ -41,6 +47,21 @@ protected JsonSerializerParameters newParameters() {
return JsonSerializerParameters.DEFAULT;
}

public String getPropertyName() {
return propertyName;
}

/**
* Serializes the property name
*
* @param writer writer
* @param bean bean containing the property to serialize
* @param ctx context of the serialization process
*/
public void serializePropertyName( JsonWriter writer, T bean, JsonSerializationContext ctx ) {
writer.unescapeName( propertyName );
}

/**
* @param bean bean containing the property to serialize
* @param ctx context of the serialization process
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package com.github.nmorel.gwtjackson.client.ser.bean;

import java.util.Map;

import com.github.nmorel.gwtjackson.client.JsonSerializationContext;
import com.github.nmorel.gwtjackson.client.JsonSerializerParameters;
import com.github.nmorel.gwtjackson.client.stream.JsonWriter;
Expand All @@ -30,8 +28,7 @@
interface InternalSerializer<T> {

void serializeInternally( JsonWriter writer, T value, JsonSerializationContext ctx, JsonSerializerParameters params,
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo, Map<String,
BeanPropertySerializer<T, ?>> serializers );
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo );

}

Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,16 @@
*
* @author Nicolas Morel
*/
public class PropertyIdentitySerializationInfo<T> implements IdentitySerializationInfo<T> {
public abstract class PropertyIdentitySerializationInfo<T, V> extends BeanPropertySerializer<T, V> implements IdentitySerializationInfo<T> {

/**
* if we always serialize the bean as an id even for the first encounter.
*/
private final boolean alwaysAsId;

/**
* Name of the property holding the identity
*/
private final String propertyName;

public PropertyIdentitySerializationInfo( boolean alwaysAsId, String propertyName ) {
super( propertyName );
this.alwaysAsId = alwaysAsId;
this.propertyName = propertyName;
}

@Override
Expand All @@ -50,13 +45,8 @@ public boolean isProperty() {
return true;
}

@Override
public String getPropertyName() {
return propertyName;
}

@Override
public ObjectIdSerializer<?> getObjectId( T bean, JsonSerializationContext ctx ) {
throw ctx.traceError( bean, "getObjectId() is not supported by PropertyIdentitySerializationInfo" );
return new ObjectIdSerializer( getValue( bean, ctx ), getSerializer() );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package com.github.nmorel.gwtjackson.client.ser.bean;

import java.util.Map;

import com.github.nmorel.gwtjackson.client.JsonSerializationContext;
import com.github.nmorel.gwtjackson.client.JsonSerializer;
import com.github.nmorel.gwtjackson.client.JsonSerializerParameters;
Expand All @@ -39,9 +37,8 @@ public abstract static class BeanSubtypeSerializer<T> extends SubtypeSerializer<

@Override
public void serializeInternally( JsonWriter writer, T value, JsonSerializationContext ctx, JsonSerializerParameters params,
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo,
Map<String, BeanPropertySerializer<T, ?>> serializers ) {
getSerializer().serializeInternally( writer, value, ctx, params, defaultIdentityInfo, defaultTypeInfo, serializers );
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo ) {
getSerializer().serializeInternally( writer, value, ctx, params, defaultIdentityInfo, defaultTypeInfo );
}
}

Expand All @@ -54,8 +51,7 @@ public abstract static class DefaultSubtypeSerializer<T> extends SubtypeSerializ

@Override
public void serializeInternally( JsonWriter writer, T value, JsonSerializationContext ctx, JsonSerializerParameters params,
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo,
Map<String, BeanPropertySerializer<T, ?>> serializers ) {
IdentitySerializationInfo<T> defaultIdentityInfo, TypeSerializationInfo<T> defaultTypeInfo ) {

final TypeSerializationInfo typeInfo = null == params.getTypeInfo() ? defaultTypeInfo : params.getTypeInfo();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,13 @@ public void close() {
}

private void string(String value) {
String[] replacements = REPLACEMENT_CHARS;
out.append("\"");
encodeString( value, out );
out.append("\"");
}

private static void encodeString(final String value, final StringBuilder out) {
String[] replacements = REPLACEMENT_CHARS;
int last = 0;
int length = value.length();
for (int i = 0; i < length; i++) {
Expand All @@ -495,7 +500,12 @@ private void string(String value) {
if (last < length) {
out.append(value, last, length);
}
out.append("\"");
}

public static String encodeString(final String value) {
StringBuilder out = new StringBuilder();
encodeString( value, out );
return out.toString();
}

private void newline() {
Expand Down
Loading

0 comments on commit 755d5c9

Please sign in to comment.