[infinispan-dev] Avoid Collections.emptySet() / emptyMap() / emptyList
Galder Zamarreño
galder at redhat.com
Tue Oct 23 08:39:34 EDT 2012
On Oct 22, 2012, at 3:40 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
> On 10/22/2012 01:41 AM, Galder Zamarreño wrote:
>>
>> On Oct 19, 2012, at 7:20 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>>
>>> Also be aware that JBMAR has specific optimizations for the JDK empty
>>> collections - they are represented by a single byte in the stream.
>>
>> Well, it's actually 3 bytes that you use to represent empty collections (at least in 1.3.15ga):
>>
>> write(ID_NEW_OBJECT);
>> write(ID_CLASS_CLASS);
>> write(classByte);
>>
>> Whereas with our externalizers, these get resolved via object writer (which gets called before your code to detect empty collections) and it only writes 1 byte:
>>
>> write(externalizerId);
>
> No, that's inaccurate; they are singletons and do not use ID_NEW_OBJECT.
Really?
https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L169
> They're done as instances so it is one of:
>
> public static final int ID_EMPTY_LIST_OBJECT = 0x5d;
> public static final int ID_EMPTY_SET_OBJECT = 0x62;
> public static final int ID_EMPTY_MAP_OBJECT = 0x69;
>
> Your externalizers on the other hand take multiple bytes even in the
> simplest case. If it is that important, you could use an ObjectResolver
> to swap in the JDK instance instead of using yet another externalizer
> (which has several bytes of overhead of its own).
Well, to be completely precise, our version will write two bytes:
1st byte: https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L140
2nd byte: https://github.com/galderz/infinispan/blob/t_memory/core/src/main/java/org/infinispan/marshall/jboss/ExternalizerTable.java#L397
I still see 3 bytes written in your case:
1st byte: https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L169
2nd byte: https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L1133
3rd byte: class byte, as indicated in https://github.com/dmlloyd/jboss-marshalling/blob/1.3.15.GA/river/src/main/java/org/jboss/marshalling/river/RiverMarshaller.java#L167
Not sure if you remember but we have ObjectTable.Writer in what we call ExternalizerTable, which given a type, it resolves into an Infinispan Externalizer.
Now, given Collections.Empty<Set>, it will resolve to an adapter that writes the ID of the externalizer (in this case InfinsipanCollections.EmptySet.Externalizer), and then will delegate to its writeObject, which does nothing.
>
> --
> - DML
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev
--
Galder Zamarreño
galder at redhat.com
twitter.com/galderz
Project Lead, Escalante
http://escalante.io
Engineer, Infinispan
http://infinispan.org
More information about the infinispan-dev
mailing list