Skip to content

Commit

Permalink
Improve performance of json schema serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
vangheem committed Nov 30, 2017
1 parent 94e475f commit fcb2af8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
@@ -1,7 +1,8 @@
2.1.14 (unreleased)
-------------------

- Nothing changed yet.
- Improve performance of json schema serialization
[vangheem]


2.1.13 (2017-11-29)
Expand Down
2 changes: 2 additions & 0 deletions guillotina/json/serialize_schema.py
Expand Up @@ -6,6 +6,7 @@
from guillotina.interfaces import IRequest
from guillotina.interfaces import ISchemaFieldSerializeToJson
from guillotina.interfaces import ISchemaSerializeToJson
from guillotina.profile import profilable
from guillotina.schema import getFieldsInOrder
from zope.interface import Interface

Expand All @@ -19,6 +20,7 @@ def __init__(self, factory, request):
self.factory = factory
self.request = request

@profilable
async def __call__(self):
factory = self.factory
result = {
Expand Down
20 changes: 15 additions & 5 deletions guillotina/json/serialize_schema_field.py
Expand Up @@ -5,6 +5,7 @@
from guillotina.interfaces import ISchemaFieldSerializeToJson
from guillotina.interfaces import ISchemaSerializeToJson
from guillotina.json.serialize_value import json_compatible
from guillotina.profile import profilable
from guillotina.schema import getFields
from guillotina.schema.interfaces import IBool
from guillotina.schema.interfaces import IChoice
Expand All @@ -24,6 +25,9 @@
from zope.interface import Interface


FIELDS_CACHE = {}


@configure.adapter(
for_=(IField, Interface, Interface),
provides=ISchemaFieldSerializeToJson)
Expand All @@ -49,14 +53,20 @@ def __init__(self, field, schema, request):
self.field = field
self.schema = schema
self.request = request
self.field_attributes = {}

@profilable
async def __call__(self):
result = {'type': self.field_type}
for schema in implementedBy(self.field.__class__).flattened():
self.field_attributes.update(getFields(schema))
for attribute_name in sorted(self.field_attributes.keys()):
attribute_field = self.field_attributes[attribute_name]
# caching the field_attributes here improves performance dramatically
if self.field.__class__ in FIELDS_CACHE:
field_attributes = FIELDS_CACHE[self.field.__class__].copy()
else:
field_attributes = {}
for schema in implementedBy(self.field.__class__).flattened():
field_attributes.update(getFields(schema))
FIELDS_CACHE[self.field.__class__] = field_attributes
for attribute_name in sorted(field_attributes.keys()):
attribute_field = field_attributes[attribute_name]
if attribute_name in self.filtered_attributes:
continue

Expand Down

0 comments on commit fcb2af8

Please sign in to comment.