Description
starting with 1.9, avro SpecificData supports per-class MODEL$ definitions, and looks for them on specific classes:
public static <T> SpecificData getForClass(Class<T> c) { if (SpecificRecordBase.class.isAssignableFrom(c)) { final Field specificDataField; try { specificDataField = c.getDeclaredField("MODEL$"); specificDataField.setAccessible(true); return (SpecificData) specificDataField.get(null); } catch (NoSuchFieldException e) { // Return default instance return SpecificData.get(); <======= EXPENSIVE } catch (IllegalAccessException e) { throw new AvroRuntimeException(e); } } return SpecificData.get(); }
when this is run vs specific record classes generated by older avro, which do not have field MODEL$ this reslts in a serious performance degradation. we've measured the impact on user code to be x3 slower in one case. here's a flame graph:
under java 7+ it should be completely possible to cache the existence (or lack thereof) of MODEL$ using ClassValue which would also speed this up when operating on classes generated by more modern avro since it would avoid reflection