Hi Avro developers,

I have been looking at the Python decimal encoding paths in
lang/py/avro/io.py, specifically BinaryEncoder.write_decimal_bytes and
write_decimal_fixed, and I have a performance improvement I would like to
contribute.

The current implementation builds the decimal output in Python and writes
it in many small chunks. My patch keeps the existing integer and
two's-complement behavior, uses int.to_bytes() to build the final encoded
bytes, and writes the payload in bulk. For fixed decimals, it also
simplifies the sign-extension logic.

I have tested it with:

   -

   200,000 randomized differential cases
   -

   8,698 boundary and direct-call cases, including negative zero and
   exception behavior
   -

   191 passing avro.test.test_io tests
   -

   formatting, lint, and type checks
   -

   identical final serialized byte streams

In profiling, function calls dropped from about 5.94 million to 1.30
million, and writer calls dropped from 1,748,228 to 162,000. Wall-clock
performance also improved, although the machine was somewhat noisy, so I do
not want to claim a fixed speedup number.

Before opening a PR, I wanted to check one compatibility detail.

Since BinaryEncoder accepts an arbitrary writer, the bulk-write version
changes things that a custom writer could observe, such as the number and
size of write() calls, the bytes or bytearray argument form in some cases,
and possibly when a custom writer raises an exception.

The final Avro byte stream is unchanged.

Would the number and shape of those individual writer calls be considered
part of the compatibility contract, or is preserving the encoded byte
stream the main requirement here?

If bulk writes are acceptable, I can open a PR with the implementation,
tests, and profiling results.

Thanks,
Nirvair Sandhu

Reply via email to