[ 
https://issues.apache.org/jira/browse/IGNITE-22544?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17859613#comment-17859613
 ] 

Ivan Bessonov edited comment on IGNITE-22544 at 6/24/24 10:00 AM:
------------------------------------------------------------------

According to 
{{{}org.apache.ignite.internal.benchmarks.UpdateCommandsMarshalingMicroBenchmark{}}}.

Before:
{code:java}
Benchmark                                         (payloadSize)  (updateAll)   
Mode  Cnt     Score     Error   Units
UpdateCommandsMarshalingMicroBenchmark.marshal              128        false  
thrpt    5  2361.249 ±  66.884  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal              128         true  
thrpt    5    52.377 ±   3.769  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048        false  
thrpt    5  1713.443 ± 331.795  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048         true  
thrpt    5    14.916 ±   2.230  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192        false  
thrpt    5   833.372 ± 227.738  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192         true  
thrpt    5     3.281 ±   0.906  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128        false  
thrpt    5  2090.845 ± 792.226  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128         true  
thrpt    5    51.393 ±  16.872  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048        false  
thrpt    5  2188.459 ±  69.423  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048         true  
thrpt    5    52.705 ±   2.771  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192        false  
thrpt    5  2174.810 ±  61.331  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192         true  
thrpt    5    53.805 ±   1.000  ops/ms {code}
After:
{code:java}
Benchmark                                         (payloadSize)  (updateAll)   
Mode  Cnt     Score      Error   Units
UpdateCommandsMarshalingMicroBenchmark.marshal              128        false  
thrpt    5  4389.765 ±   66.332  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal              128         true  
thrpt    5    79.684 ±    0.965  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048        false  
thrpt    5  2754.506 ±   58.151  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048         true  
thrpt    5    17.435 ±    0.267  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192        false  
thrpt    5  1066.381 ±   10.254  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192         true  
thrpt    5     3.389 ±    0.688  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128        false  
thrpt    5  2782.648 ±  173.791  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128         true  
thrpt    5    69.952 ±    9.109  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048        false  
thrpt    5  2752.568 ±   50.796  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048         true  
thrpt    5    63.721 ±    2.902  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192        false  
thrpt    5  2676.343 ± 1209.184  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192         true  
thrpt    5    62.139 ±   17.144  ops/ms {code}
Short summary:
 * Depending on the number of byte arrays inside of the message (which can't be 
optimized), marshaling became from 0% to 85% faster according to created 
benchmark, due to a combination of a lot of different optimizations, such as
 ** avoiding the creation of serializers
 ** simpler and slightly faster byte buffers pool
 ** better binary UUID format
 ** low-level stuff in direct stream
 ** better {{writeVarInt}} / {{writeVarLong}}
 * If we take a look at the flamegraph, we could see that serialization itself 
is about 1.5-2.0 times slower than the following {{{}Arrays.copyOf{}}}, which 
is pretty good in my opinion.
 * Reading speed wasn't so thoroughly checked in this issue, I created another 
one: https://issues.apache.org/jira/browse/IGNITE-22559
Overall, reading speed doesn't depend on the size of individual byte buffers, 
because we simple wrap the original array. Other then that, current 
optimizations show 15%-35% increase in deserialization speed, due to
 ** {{...StreamImplV1}} optimizations
 ** faster {{readInt}} / {{readLong}}
 ** better binary UUID format

 * Further optimizations for reads are required. Here I mostly focused on 
writing speed. Reading speed turned out to be worse than writing speed for 
small commands, I don't like it.


was (Author: ibessonov):
According to 
{{{}org.apache.ignite.internal.benchmarks.UpdateCommandsMarshalingMicroBenchmark{}}}.

Before:
{code:java}
Benchmark                                         (payloadSize)  (updateAll)   
Mode  Cnt     Score     Error   Units
UpdateCommandsMarshalingMicroBenchmark.marshal              128        false  
thrpt    5  2361.249 ±  66.884  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal              128         true  
thrpt    5    52.377 ±   3.769  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048        false  
thrpt    5  1713.443 ± 331.795  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048         true  
thrpt    5    14.916 ±   2.230  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192        false  
thrpt    5   833.372 ± 227.738  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192         true  
thrpt    5     3.281 ±   0.906  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128        false  
thrpt    5  2090.845 ± 792.226  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128         true  
thrpt    5    51.393 ±  16.872  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048        false  
thrpt    5  2188.459 ±  69.423  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048         true  
thrpt    5    52.705 ±   2.771  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192        false  
thrpt    5  2174.810 ±  61.331  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192         true  
thrpt    5    53.805 ±   1.000  ops/ms {code}
After:
{code:java}
Benchmark                                         (payloadSize)  (updateAll)   
Mode  Cnt     Score      Error   Units
UpdateCommandsMarshalingMicroBenchmark.marshal              128        false  
thrpt    5  4389.765 ±   66.332  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal              128         true  
thrpt    5    79.684 ±    0.965  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048        false  
thrpt    5  2754.506 ±   58.151  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             2048         true  
thrpt    5    17.435 ±    0.267  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192        false  
thrpt    5  1066.381 ±   10.254  ops/ms
UpdateCommandsMarshalingMicroBenchmark.marshal             8192         true  
thrpt    5     3.389 ±    0.688  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128        false  
thrpt    5  2782.648 ±  173.791  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal            128         true  
thrpt    5    69.952 ±    9.109  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048        false  
thrpt    5  2752.568 ±   50.796  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           2048         true  
thrpt    5    63.721 ±    2.902  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192        false  
thrpt    5  2676.343 ± 1209.184  ops/ms
UpdateCommandsMarshalingMicroBenchmark.unmarshal           8192         true  
thrpt    5    62.139 ±   17.144  ops/ms {code}
Short summary:
 * Depending on the number of byte arrays inside of the message (which can't be 
optimized), marshaling became from 0% to 85% faster according to created 
benchmark, due to a combination of a lot of different optimizations, such as
 ** avoiding the creation of serializers
 ** simpler and slightly faster byte buffers pool
 ** better binary UUID format
 ** low-level stuff in direct stream
 ** better {{writeVarInt}} / {{writeVarLong}}
 * If we take a look at the flamegraph, we could see that serialization itself 
is about 1.5-2.0 times slower than the following {{{}Arrays.copyOf{}}}, which 
is pretty good in my opinion.
 * Reading speed wasn't so thoroughly checked in this issue, I created another 
one: https://issues.apache.org/jira/browse/IGNITE-22559
Overall, reading speed doesn't depend on the size of individual byte buffers, 
because we simple wrap the original array. Other then that, current 
optimizations show 15%-35% increase in deserialization speed, due to
 ** {{...StreamImplV1}} optimizations
 ** faster {{readInt}} / {{readLong}}
 ** better binary UUID format

 *  
 * Further optimizations for reads are required. Here I mostly focused on 
writing speed. Reading speed turned out to be worse than writing speed for 
small commands, I don't like it.

> Commands marshalling appears to be slow
> ---------------------------------------
>
>                 Key: IGNITE-22544
>                 URL: https://issues.apache.org/jira/browse/IGNITE-22544
>             Project: Ignite
>          Issue Type: Improvement
>            Reporter: Ivan Bessonov
>            Assignee: Ivan Bessonov
>            Priority: Major
>              Labels: ignite-3, ignite3_performance
>         Attachments: IGNITE-22544.patch
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> We should benchmark the way we marshal commands using optimized marshaller 
> and make it faster. Some obvious places:
>  * byte buffers pool - we can replace queue with a manual implementation of 
> Treiber stack, it's trivial and doesn't use as many CAS/volatile operations
>  * new serializers are allocated every time, but they can be put into static 
> final constants instead, or cached in fields of corresponding factories
>  * we can create a serialization factory per group, not per message, this way 
> we will remove unnecessary indirection. Group factory can use {{{}switch{}}}, 
> like in Ignite 2, which would basically lead to static dispatch of 
> deserializer constructors and static access to serializers, instead of 
> dynamic dispatch (virtual call), which should be noticeably faster
>  * profiler might show other simple places, we must also compare 
> {{OptimizedMarshaller}} against other serialization algorithms in benchmarks
> EDIT: quick draft attached, it addresses points 1 and 2.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to