Optimize read - decimal, logical type
MODIFY
fastavro/_read.pyx
fastavro/_read.pyx
import bz2
import zlib
import datetime
-from decimal import localcontext, Decimal
+from decimal import Context
from fastavro.six import MemoryIO
from uuid import UUID
@@ -53,6 +53,8 @@ AVRO_TYPES = {
'error_union'
}
+decimal_context = Context()
+
ctypedef int int32
ctypedef unsigned int uint32
@@ -183,10 +185,9 @@ cpdef read_decimal(data, writer_schema=None, reader_schema=None):
unscaled_datum = be_signed_bytes_to_int(data)
- with localcontext() as ctx:
- ctx.prec = precision
- scaled_datum = Decimal(unscaled_datum).scaleb(-scale)
- return scaled_datum
+ decimal_context.prec = precision
+ return decimal_context.create_decimal(unscaled_datum).\
+ scaleb(-scale, decimal_context)
cdef long64 read_long(fo,
@@ -512,7 +513,6 @@ cpdef _read_data(fo, writer_schema, reader_schema=None, return_record_name=False
"""Read data from file object according to schema."""
record_type = extract_record_type(writer_schema)
- logical_type = extract_logical_type(writer_schema)
if reader_schema and record_type in AVRO_TYPES:
# If the schemas are the same, set the reader schema to None so that no
@@ -560,6 +560,7 @@ cpdef _read_data(fo, writer_schema, reader_schema=None, return_record_name=False
raise EOFError('cannot read %s from %s' % (record_type, fo))
if 'logicalType' in writer_schema:
+ logical_type = extract_logical_type(writer_schema)
fn = LOGICAL_READERS.get(logical_type)
if fn:
return fn(data, writer_schema, reader_schema)

MODIFY
fastavro/_read_py.py
fastavro/_read_py.py
@@ -11,7 +11,7 @@ from struct import error as StructError
import bz2
import zlib
import datetime
-from decimal import localcontext, Decimal
+from decimal import Context
from uuid import UUID
import json
@@ -53,6 +53,8 @@ AVRO_TYPES = {
'error_union'
}
+decimal_context = Context()
+
def match_types(writer_type, reader_type):
if isinstance(writer_type, list) or isinstance(reader_type, list):
@@ -161,10 +163,9 @@ def read_decimal(data, writer_schema=None, reader_schema=None):
unscaled_datum = be_signed_bytes_to_int(data)
- with localcontext() as ctx:
- ctx.prec = precision
- scaled_datum = Decimal(unscaled_datum).scaleb(-scale)
- return scaled_datum
+ decimal_context.prec = precision
+ return decimal_context.create_decimal(unscaled_datum). \
+ scaleb(-scale, decimal_context)
def read_int(decoder, writer_schema=None, reader_schema=None):
@@ -405,7 +406,6 @@ def read_data(decoder, writer_schema, reader_schema=None,
"""Read data from file object according to schema."""
record_type = extract_record_type(writer_schema)
- logical_type = extract_logical_type(writer_schema)
if reader_schema and record_type in AVRO_TYPES:
# If the schemas are the same, set the reader schema to None so that no
@@ -429,6 +429,7 @@ def read_data(decoder, writer_schema, reader_schema=None,
)
if 'logicalType' in writer_schema:
+ logical_type = extract_logical_type(writer_schema)
fn = LOGICAL_READERS.get(logical_type)
if fn:
return fn(data, writer_schema, reader_schema)

Optimize read - decimal, logical type