Skip to content

Commit

Permalink
Optimize BeanSerializer by using "blocks of 4" unrolling for bigger…
Browse files Browse the repository at this point in the history
… pojos
  • Loading branch information
cowtowncoder committed Oct 29, 2017
1 parent 79fcdef commit 9417933
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 103 deletions.
Expand Up @@ -140,12 +140,21 @@ public final void serialize(Object bean, JsonGenerator gen, SerializerProvider p
_serializeWithObjectId(bean, gen, provider, true); _serializeWithObjectId(bean, gen, provider, true);
return; return;
} }
gen.writeStartObject(bean);
if (_propertyFilterId != null) { if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, gen, provider); gen.writeStartObject(bean);
} else { _serializeFieldsFiltered(bean, gen, provider, _propertyFilterId);
serializeFields(bean, gen, provider); gen.writeEndObject();
return;
} }
BeanPropertyWriter[] fProps = _filteredProps;
if ((fProps != null) && (provider.getActiveView() != null)) {
gen.writeStartObject(bean);
_serializeFieldsWithView(bean, gen, provider, fProps);
gen.writeEndObject();
return;
}
gen.writeStartObject(bean);
_serializeFieldsNoView(bean, gen, provider, _props);
gen.writeEndObject(); gen.writeEndObject();
} }
} }
Expand Up @@ -21,7 +21,13 @@ public class UnrolledBeanSerializer
{ {
private static final long serialVersionUID = 30; // as per jackson 3.0 private static final long serialVersionUID = 30; // as per jackson 3.0


public static final int MAX_PROPS = 6; /* 28-Oct-2017, tatu: Exact choice for max number of properties to unroll
* is difficult to pin down, but probably has to be at least 4, and
* at most 8. Partly this is due to "blocks of 4" that default bean
* serializer now uses, and partly guessing how aggressively JVM might
* inline larger methods (more unroll, bigger method).
*/
private static final int MAX_PROPS = 6;


protected final int _propCount; protected final int _propCount;


Expand Down Expand Up @@ -145,8 +151,11 @@ public void serialize(Object bean, JsonGenerator gen, SerializerProvider provide
// NOTE! We have ensured that "JSON Filter" and "Object Id" cases // NOTE! We have ensured that "JSON Filter" and "Object Id" cases
// always use "vanilla" BeanSerializer, so no need to check here // always use "vanilla" BeanSerializer, so no need to check here


if ((_filteredProps != null) && (provider.getActiveView() != null)) { BeanPropertyWriter[] fProps = _filteredProps;
serializeWithView(bean, gen, provider, _filteredProps); if ((fProps != null) && (provider.getActiveView() != null)) {
gen.writeStartObject(bean);
_serializeFieldsWithView(bean, gen, provider, fProps);
gen.writeEndObject();
return; return;
} }
serializeNonFiltered(bean, gen, provider); serializeNonFiltered(bean, gen, provider);
Expand Down Expand Up @@ -197,64 +206,4 @@ protected void serializeNonFiltered(Object bean, JsonGenerator gen, SerializerPr
} }
gen.writeEndObject(); gen.writeEndObject();
} }

protected void serializeWithView(Object bean, JsonGenerator gen, SerializerProvider provider,
BeanPropertyWriter[] props)
throws IOException
{
gen.writeStartObject(bean);
BeanPropertyWriter prop = null;

try {
// NOTE: slightly less optimal as we do not use local variables, need offset
final int offset = props.length-1;
switch (_propCount) {
default:
//case 6:
prop = props[offset-5];
if (prop != null) { // can have nulls in filtered list
prop.serializeAsField(bean, gen, provider);
}
// fall through
case 5:
prop = props[offset-4];
if (prop != null) { // can have nulls in filtered list
prop.serializeAsField(bean, gen, provider);
}
case 4:
prop = props[offset-3];
if (prop != null) { // can have nulls in filtered list
prop.serializeAsField(bean, gen, provider);
}
case 3:
prop = props[offset-2];
if (prop != null) { // can have nulls in filtered list
prop.serializeAsField(bean, gen, provider);
}
case 2:
prop = props[offset-1];
if (prop != null) { // can have nulls in filtered list
prop.serializeAsField(bean, gen, provider);
}
case 1:
prop = props[offset];
if (prop != null) { // can have nulls in filtered list
prop.serializeAsField(bean, gen, provider);
}
}
prop = null;
if (_anyGetterWriter != null) {
_anyGetterWriter.getAndSerialize(bean, gen, provider);
}
} catch (Exception e) {
String name = (prop == null) ? "[anySetter]" : prop.getName();
wrapAndThrow(provider, e, bean, name);
} catch (StackOverflowError e) {
JsonMappingException mapE = new JsonMappingException(gen, "Infinite recursion (StackOverflowError)", e);
String name = (prop == null) ? "[anySetter]" : prop.getName();
mapE.prependPath(new JsonMappingException.Reference(bean, name));
throw mapE;
}
gen.writeEndObject();
}
} }
Expand Up @@ -117,12 +117,17 @@ public final void serialize(Object bean, JsonGenerator gen, SerializerProvider p
// (although... is that a problem, overwriting it now?) // (although... is that a problem, overwriting it now?)
gen.setCurrentValue(bean); // [databind#631] gen.setCurrentValue(bean); // [databind#631]
if (_propertyFilterId != null) { if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, gen, provider); _serializeFieldsFiltered(bean, gen, provider, _propertyFilterId);
} else { return;
serializeFields(bean, gen, provider); }
BeanPropertyWriter[] fProps = _filteredProps;
if ((fProps != null) && (provider.getActiveView() != null)) {
_serializeFieldsWithView(bean, gen, provider, fProps);
return;
} }
_serializeFieldsNoView(bean, gen, provider, _props);
} }

@Override @Override
public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider provider, public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider provider,
TypeSerializer typeSer) throws IOException TypeSerializer typeSer) throws IOException
Expand All @@ -135,12 +140,18 @@ public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider
_serializeWithObjectId(bean, gen, provider, typeSer); _serializeWithObjectId(bean, gen, provider, typeSer);
return; return;
} }
gen.setCurrentValue(bean); // [databind#631] // Because we do not write start-object need to call this explicitly:
gen.setCurrentValue(bean);
if (_propertyFilterId != null) { if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, gen, provider); _serializeFieldsFiltered(bean, gen, provider, _propertyFilterId);
} else { return;
serializeFields(bean, gen, provider); }
BeanPropertyWriter[] fProps = _filteredProps;
if ((fProps != null) && (provider.getActiveView() != null)) {
_serializeFieldsWithView(bean, gen, provider, fProps);
return;
} }
_serializeFieldsNoView(bean, gen, provider, _props);
} }


/* /*
Expand Down

0 comments on commit 9417933

Please sign in to comment.