[ http://issues.apache.org/jira/browse/HADOOP-87?page=all ]

Hairong Kuang updated HADOOP-87:
--------------------------------

    Attachment: hadoop_87.fix

> SequenceFile performance degrades substantially compression is on and large 
> values are encountered
> --------------------------------------------------------------------------------------------------
>
>          Key: HADOOP-87
>          URL: http://issues.apache.org/jira/browse/HADOOP-87
>      Project: Hadoop
>         Type: Improvement
>   Components: io
>     Versions: 0.1
>     Reporter: Sameer Paranjpye
>      Fix For: 0.1
>  Attachments: hadoop_87.fix
>
> The code snippet in quesiton is:
>      if (deflateValues) {
>         deflateIn.reset();
>         val.write(deflateIn);
>         deflater.reset();
>         deflater.setInput(deflateIn.getData(), 0, deflateIn.getLength());
>         deflater.finish();
>         while (!deflater.finished()) {
>           int count = deflater.deflate(deflateOut);
>           buffer.write(deflateOut, 0, count);
>         }
>       } else {
>   
> A couple of issues with this code:
> 1. The value is serialized to the 'deflateIn' buffer which is an instance of 
> 'DataOutputBuffer', this grows as large as needed to store the serialized 
> value and stays as large as the largest serialized value encountered. If, for 
> instance a stream has a single 8MB value followed by several 8KB values the 
> size of the buffer stays at 8MB. The problem is that the *entire* 8MB buffer 
> is always copied over the JNI boundary regardless of the size of the value. 
> We've observed this over several runs where compression performance degrades 
> by a couple of orders of magnitude when a very large value is encountered. 
> Shrinking the buffer fixes the problem.
> 2. Data is copied lots of times. First the value is serialized into 
> 'deflateIn'. Second, the value is copied over the JNI boundary in *every* 
> iteration of the while loop. Third, the compressed data is copied piecemeal 
> into 'deflateOut'. Finally, it is appended to 'buffer'.
> Proposed fix:
> 1. Don't let big buffers persist. Allow 'deflateIn' to grow to a *persistent* 
> maximum reasonable size, say 64KB. If a larger value is encountered, grow the 
> buffer in order to process the value, then shrink it back to the maximum 
> size. To do this, we add a 'reset' method which takes a buffer size.
> 2. Don't use a loop to deflate. The maximum size of the output can be 
> determined by 'maxOutputSize = inputSize * 1.01 + 12'. This is the maximum 
> output size that zlib will produce. We allocate a large enough output buffer 
> and compress everything in 1 pass. The output buffer, of course, needs to 
> shrink as well.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to