Igniters,
I was a bit concerned about portable marshalling performance in .Net and performed a very quick and dirty evaluation of the following optimizations: 1) For non-"marshal-aware" objects metadata is constant and can be calculated in advance and only once. 2) The same goes for field IDs - we can calculate them only once. 3) Some small writes can be merged into a bigger one. E.g. 1 byte header + 1 byte user flag + 4 bytes type ID can be written as 1 pre-calculated long. In some cases writeInt(fieldId) + writeInt(fieldLen) == writeLong([constant]), etc.. 4) No need for raw-mode checks for non-"marshal-aware" objects. 5) Memory bounds checks can be removed in lots cases when fields are of fixed size. 6) In extreme scenario of object having all fields of a fixed size it can be written as follows: [request enough memory] + [constant_part1] + [field1] + [constant_part2] + [field2] + [...]. Deeper work on this can give even more ideas. When I applied some of these things in .Net it gave me about ~40% marshalling throughput increase in particular scenario. For .Net this is very important because marshalling is one of the main reasons why it is slower than Java. Being a micro-opt separately, together these things can significantly reduce marshalling CPU consumption. Probably we can use some of these techniques in Java as well. Vladimir. |
Vladimir,
Good suggestions! Could you create a JIRA ticket and put your thoughts there? It makes sense to optimized the portable marshaller in Java as well. -- Denis On 9/23/2015 1:38 PM, Vladimir Ozerov wrote: > Igniters, > > I was a bit concerned about portable marshalling performance in .Net and > performed a very quick and dirty evaluation of the following optimizations: > > 1) For non-"marshal-aware" objects metadata is constant and can be > calculated in advance and only once. > 2) The same goes for field IDs - we can calculate them only once. > 3) Some small writes can be merged into a bigger one. E.g. 1 byte header + > 1 byte user flag + 4 bytes type ID can be written as 1 pre-calculated long. > In some cases writeInt(fieldId) + writeInt(fieldLen) == > writeLong([constant]), etc.. > 4) No need for raw-mode checks for non-"marshal-aware" objects. > 5) Memory bounds checks can be removed in lots cases when fields are of > fixed size. > 6) In extreme scenario of object having all fields of a fixed size it can > be written as follows: [request enough memory] + [constant_part1] + > [field1] + [constant_part2] + [field2] + [...]. > > Deeper work on this can give even more ideas. > > When I applied some of these things in .Net it gave me about ~40% > marshalling throughput increase in particular scenario. For .Net this is > very important because marshalling is one of the main reasons why it is > slower than Java. > > Being a micro-opt separately, together these things can significantly > reduce marshalling CPU consumption. > > Probably we can use some of these techniques in Java as well. > > Vladimir. > |
Free forum by Nabble | Edit this page |