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

Leo Romanoff commented on AVRO-1282:
------------------------------------

>How much do those improvements help the Generic tests? I assume they are still 
>dominated by 
>the issues with the decoder. Although decreasing the time of a Float read by 
>35% is a big win, 
>it is a small part of what happens with Generic/Specific/Reflect reading. Does 
>using unsafe 
>here break anything if the system's byte order does not match?

Well, if you mean the last numbers I posted, they were because of using Unsafe 
for IO. I.e. it should provide the same kind of speedups to any of 
Generic/Specific/Reflect as it simply provides a faster stream implementation.


> Your results for reading Floats/Doubles above are slower than mine, is this 
> because you are 
> now populating an array when reading as well? 

Yes. There are a few reasons for populating the array when reading:

1) Make it more symmetric to writing, as writing in FloatTest/DoubleTest always 
iterates over an array. And it means additional memory accesses, which also 
have their cost.

2) It is more realistic scenario, as most deserializers would store results 
somewhere. And as I just mentioned, storing comes at cost of memory access. And 
those memory accesses seem to have a very big impact on the performance.

3) For scehma-based serialization performance tests like Reflect-based, it is 
almost impossible to decouple pure reading from storing the result somewhere. 
Therefore it is unfair (or useless) to compare them with vanilla 
FloatTest/DoubleTest reading speeds as they measure different things. With my 
little change to reading it seems to make more sense.

> The benchmark was intended to isolate (as best as possible) the read and 
> write portions of 
> the decoder/encoder? I'd be interested in looking at this code.

The code change is trivial. It is in the readInternal. It basically allocates 
an array before a loop and then inside a loop it assigns each read object to a 
corresponding array element, thus filling the array with a content.

> As for arrays of primitives, we should look into Group varint encoding and 
> similar 
> techniques: ...

Yes, I've seen this paper before. IMHO, it is faster than the usual varint 
encoding, but it will be slower (though more space efficient) than what 
Unsafe-based primitive arrays serialization does. And the reason for this is 
the number of memory accesses and branching. Unsafe-based array serialization 
just copies bytes and it does it in chunks of 4 or 8 bytes per instruction. No 
branching at all. You can hardly beat it, I'd say. 
(As a remark, I've experimented with Kryo and have seen that Kryo using 
Unsafe-based IO + LZ-like compression on top of it is often faster than Kryo 
using varing encoding for the same content while producing a compressed output 
of comparable size)

> In general, lets separate out the Unsafe enhancements for Reflection from 
> those that are 
> for the Input/Output streams. Lets get the reflection work in this ticket 
> done and 
> committed, then move on to other enhancements.

I agree. We should not mix to many things in this ticket.

> A third related to other non-Unsafe performance improvements, for example 
> those you allude 
> to with:
> Coming back to your message about reading doubles and floats and observation 
> that they are 
> much slower with ReflectDatumReader/Writer. I just did some profiling and 
> found some 
> issues. With small changes, I could significantly improve write performance 
> and improved a 
> bit read performance. All this without Unsafe reads/writes into streams yet.

This one is still in scope of this ticket, IMHO. It affects only 
ReflectDatumReader/Writer and the changes are mostly in my ArrayAccessor class. 
I'll provide an updated patch today.

BTW, should I include TestFloat's/TestDouble's readInternal changes mentioned 
above into this patch or should I leave them out?

                
> Make use of the sun.misc.Unsafe class during serialization if a JDK supports 
> it
> -------------------------------------------------------------------------------
>
>                 Key: AVRO-1282
>                 URL: https://issues.apache.org/jira/browse/AVRO-1282
>             Project: Avro
>          Issue Type: Improvement
>          Components: java
>    Affects Versions: 1.7.4
>            Reporter: Leo Romanoff
>            Priority: Minor
>         Attachments: avro-1282-v1.patch, avro-1282-v2.patch, 
> avro-1282-v3.patch, avro-1282-v4.patch, avro-1282-v5.patch, avro-1282-v6.patch
>
>
> Unsafe can be used to significantly speed up serialization process, if a JDK 
> implementation supports java.misc.Unsafe properly. Most JDKs running on PCs 
> support it. Some platforms like Android lack a proper support for Unsafe yet.
> There are two possibilities to use Unsafe for serialization:
> 1) Very quick access to the fields of objects. It is way faster than with the 
> reflection-based approach using Field.get/set
> 2) Input and Output streams can be using Unsafe to perform very quick 
> input/output.
>  
> 3) More over, Unsafe makes it possible to serialize to/deserialize from 
> off-heap memory directly and very quickly, without any intermediate buffers 
> allocated on heap. There is virtually no overhead compared to the usual byte 
> arrays.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to