From cc8e2a1d65231158952dd51df01b42f7e0c20e5b Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 29 Nov 2016 10:38:49 -0700 Subject: [PATCH 01/37] Fix name of Lollipop --- subjects/loli.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/subjects/loli.py b/subjects/loli.py index bca724a..e230409 100644 --- a/subjects/loli.py +++ b/subjects/loli.py @@ -1,12 +1,11 @@ from collections import namedtuple - from lollipop.types import Object, String, Integer, List, FunctionField, MethodField +__name__ = 'Lollipop' + SubS = namedtuple('SubS', ['w', 'x', 'y', 'z']) ComplexS = namedtuple('ComplexS', ['foo', 'bar', 'sub', 'subs']) -__name__ == 'lollipop' - def get_x(obj): return obj.x + 10 From 0ddd5e220c8e85ecb825891fb22ea835d3e9b4cf Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 29 Nov 2016 10:41:29 -0700 Subject: [PATCH 02/37] Fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0de678..1484e47 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ You can find the latest benchmarks on [this page](https://voidfiles.github.io/py Currently the following projects are benchmarked. -* [Colander](http://docs.pylonsproject.org/projects/colander/en/latest/) * [Django REST framework](http://www.django-rest-framework.org/) * [serpy](https://github.com/clarkduvall/serpy) * [marshmallow](https://marshmallow.readthedocs.io/en/latest/) * [Strainer](https://github.com/voidfiles/strainer) +* [Lollipop](https://github.com/maximkulkin/lollipop) Along with a baseline of a custom function that doesn't use a framework. From 715e3d29c138eea952540b99d305c913a52391cf Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 29 Nov 2016 10:42:05 -0700 Subject: [PATCH 03/37] One more Readme fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1484e47..cd59d92 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,5 @@ Currently the following projects are benchmarked. Along with a baseline of a custom function that doesn't use a framework. -Each framework is asked to serialize a list of 2 objcts a 1000 times, and then 1 object a 1000 times. +Each framework is asked to serialize a list of 2 objects a 1000 times, and then 1 object a 1000 times. From 1052ef2d0a1a9f20a32f6a70b34517199b2b8fbd Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 29 Nov 2016 10:54:55 -0700 Subject: [PATCH 04/37] Bump pystrainer version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f2e3ea6..172f71b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ serpy==0.1.1 djangorestframework==3.5.3 django==1.9 pytest -pystrainer==0.0.4 +pystrainer==0.0.5 tabulate==0.7.7 lollipop==1.0.1 markdown From 1b3424b0e28fffcc9e94c377fd064c75faaab03c Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 29 Nov 2016 23:19:09 -0700 Subject: [PATCH 05/37] Updating report --- README.md | 11 +++---- create_report.sh | 16 +++++++-- disscussion.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 disscussion.md diff --git a/README.md b/README.md index cd59d92..2be2da8 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,9 @@ You can find the latest benchmarks on [this page](https://voidfiles.github.io/py Currently the following projects are benchmarked. * [Django REST framework](http://www.django-rest-framework.org/) -* [serpy](https://github.com/clarkduvall/serpy) -* [marshmallow](https://marshmallow.readthedocs.io/en/latest/) +* [serpy](http://serpy.readthedocs.io/) +* [Marshmallow](https://marshmallow.readthedocs.io/en/latest/) * [Strainer](https://github.com/voidfiles/strainer) -* [Lollipop](https://github.com/maximkulkin/lollipop) - -Along with a baseline of a custom function that doesn't use a framework. - -Each framework is asked to serialize a list of 2 objects a 1000 times, and then 1 object a 1000 times. +* [Lollipop](http://lollipop.readthedocs.io/en/latest/) +Along with a baseline custom function that doesn't use a framework. diff --git a/create_report.sh b/create_report.sh index 8e2adf2..320a75c 100755 --- a/create_report.sh +++ b/create_report.sh @@ -1,8 +1,18 @@ #! /bin/bash cat README.md > REPORT.md -echo "
" >> REPORT.md
+echo "\`\`\`" >> REPORT.md
 python benchmark.py >> REPORT.md
-echo "
" >> REPORT.md +echo "\`\`\`" >> REPORT.md +cat disscussion.md >> REPORT.md mkdir -p out -python -m markdown REPORT.md > out/index.html +echo '' > out/index.html +echo '' >> out/index.html +echo '' >> out/index.html +echo '' >> out/index.html +echo '' >> out/index.html +echo '
' >> out/index.html +python -m markdown -x markdown.extensions.fenced_code REPORT.md >> out/index.html +echo '
' >> out/index.html +echo '' >> out/index.html +echo '' >> out/index.html diff --git a/disscussion.md b/disscussion.md new file mode 100644 index 0000000..6dfe2cb --- /dev/null +++ b/disscussion.md @@ -0,0 +1,85 @@ +## The Benchmark + +Each framework is asked to serialize a list of 2 objects a 1000 times, and then 1 object a 1000 times. + +This is the current object that is being serialized. + +```python +class ChildTestObject(object): + def __init__(self, multiplier=None): + self.w = 1000 * multiplier if multiplier else 100 + self.x = 20 * multiplier if multiplier else 20 + self.y = 'hello' * multiplier if multiplier else 'hello' + self.z = 10 * multiplier if multiplier else 10 + + +class ParentTestObject(object): + def __init__(self): + self.foo = 'bar' + self.sub = ChildTestObject() + self.subs = [ChildTestObject(i) for i in xrange(10)] + + def bar(self): + return 5 + +benchmark_object = ParentTestObject() +``` + +## Discussion + +Serialization from python objects to JSON, XML, or other transmission formats is a common task for many web related projects. In order to fill that need a number of frameworks have arised. While their aims are similar, they don't all share the same attributes. Here are how some of the features comapre. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProjectSerializationEncodingDeserializationValidation
Django REST FrameworkYesYesYesYes
serpyYesNoNoNo
marshmallowYesYesYesYes
LollipopYesNoYesYes
strainerYesYesYesYes
+ +* **Serialization**: Does the framework provide a way of serializing python objects to simple datastructures +* **Encoding**: Does the framework provide a way of encoding data into a wire format +* **Deserialization**: Does the framework provide a way of deserializing simple data structures into complex data structures +* **Validation**: Does the framework provide a way of validating datastructures, and reprorting error conditions +* **Part of Framework**: Is serialization apart of a larger framework From c41695797559c455256db5ff5d0857ed81129048 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sat, 10 Dec 2016 23:01:31 -0700 Subject: [PATCH 06/37] Bump Strainer version --- requirements.txt | 2 +- subjects/strain.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index 172f71b..67fd1a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ serpy==0.1.1 djangorestframework==3.5.3 django==1.9 pytest -pystrainer==0.0.5 +pystrainer==1.0.0 tabulate==0.7.7 lollipop==1.0.1 markdown diff --git a/subjects/strain.py b/subjects/strain.py index 2f48f73..1183e40 100644 --- a/subjects/strain.py +++ b/subjects/strain.py @@ -2,16 +2,16 @@ __name__ = 'Strainer' -sub_strainer_serializer = strainer.create_serializer( +sub_strainer_serializer = strainer.serializer( strainer.field('w'), - strainer.field('x', to_representation=lambda obj: obj.x + 10), + strainer.field('x', attr_getter=lambda obj: obj.x + 10), strainer.field('y'), strainer.field('z'), ) -complex_strainer_serializer = strainer.create_serializer( +complex_strainer_serializer = strainer.serializer( strainer.field('foo'), - strainer.field('bar', to_representation=lambda obj: obj.bar()), + strainer.field('bar', attr_getter=lambda obj: obj.bar()), strainer.child('sub', serializer=sub_strainer_serializer), strainer.many('subs', serializer=sub_strainer_serializer), ) @@ -19,6 +19,6 @@ def serialization_func(obj, many): if many: - return [complex_strainer_serializer.to_representation(x) for x in obj] + return [complex_strainer_serializer.serialize(x) for x in obj] else: - return complex_strainer_serializer.to_representation(obj) + return complex_strainer_serializer.serialize(obj) From d1b4c4bfeb6ccffe27b5adb1de3f14ab6dd2ce7c Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 21 Mar 2017 09:13:54 -0700 Subject: [PATCH 07/37] Bump pystrainer --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 67fd1a3..d3b5aaa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ serpy==0.1.1 djangorestframework==3.5.3 django==1.9 pytest -pystrainer==1.0.0 +pystrainer==1.1.1 tabulate==0.7.7 lollipop==1.0.1 markdown From 4197a665f297a5d3347f36952e9f988db6c5e3d3 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Tue, 21 Mar 2017 09:16:10 -0700 Subject: [PATCH 08/37] dump other projects --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d3b5aaa..da2f416 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -marshmallow==2.10.4 +marshmallow==2.13.4 serpy==0.1.1 -djangorestframework==3.5.3 +djangorestframework==3.6.2 django==1.9 pytest pystrainer==1.1.1 From 306488bfdf0dcab863bb70d00c72b301dc8205e1 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Wed, 12 Apr 2017 14:38:58 -0600 Subject: [PATCH 09/37] Add kim to serialization benchmark New serializtion and marshallaing library was on HN today ping: @mikeywaites --- README.md | 1 + benchmark.py | 4 ++-- requirements.txt | 3 ++- subjects/k.py | 42 +++++++++++++++++++++++++++++++++++++++ tests/test_serializers.py | 7 +++++-- 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 subjects/k.py diff --git a/README.md b/README.md index 2be2da8..5734311 100644 --- a/README.md +++ b/README.md @@ -11,5 +11,6 @@ Currently the following projects are benchmarked. * [Marshmallow](https://marshmallow.readthedocs.io/en/latest/) * [Strainer](https://github.com/voidfiles/strainer) * [Lollipop](http://lollipop.readthedocs.io/en/latest/) +* [kim](http://kim.readthedocs.io/en/latest/) Along with a baseline custom function that doesn't use a framework. diff --git a/benchmark.py b/benchmark.py index e8d9dd9..bc21a40 100644 --- a/benchmark.py +++ b/benchmark.py @@ -2,10 +2,10 @@ from tabulate import tabulate from contextlib import contextmanager -from subjects import (marsh, rf, serp, strain, hand, loli) +from subjects import (marsh, rf, serp, strain, hand, loli, k) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, hand, loli) +SUBJECTS = (marsh, rf, serp, strain, hand, loli, k) test_object = ParentTestObject() diff --git a/requirements.txt b/requirements.txt index da2f416..e20c1c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,5 +5,6 @@ django==1.9 pytest pystrainer==1.1.1 tabulate==0.7.7 -lollipop==1.0.1 +lollipop==1.1.2 +py-kim==1.0.3 markdown diff --git a/subjects/k.py b/subjects/k.py new file mode 100644 index 0000000..66a8b64 --- /dev/null +++ b/subjects/k.py @@ -0,0 +1,42 @@ +from kim import Mapper, field + +__name__ = 'kim' + + +class Complex(object): + pass + + +class SubResource(object): + pass + + +def bar_pipe(session): + session.output['bar'] = session.data() + + +def x_pipe(session): + session.output['x'] = session.data + 10 + + +class SubMapper(Mapper): + __type__ = SubResource + w = field.String() + x = field.String(extra_serialize_pipes={'output': [x_pipe]}) + y = field.String() + z = field.String() + + +class ComplexMapper(Mapper): + __type__ = Complex + foo = field.String() + bar = field.String(extra_serialize_pipes={'output': [bar_pipe]}) + sub = field.Nested(SubMapper) + subs = field.Collection(field.Nested(SubMapper)) + + +def serialization_func(obj, many): + if many: + return [ComplexMapper(obj=x).serialize() for x in obj] + else: + return ComplexMapper(obj=obj).serialize() diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 64eaa83..a7b0a67 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,4 +1,4 @@ -from subjects import marsh, rf, serp, strain, hand, loli +from subjects import marsh, rf, serp, strain, hand, loli, k from data import ParentTestObject TARGET = { @@ -32,7 +32,7 @@ def test_serializers(): test_object = ParentTestObject() - for subject in (rf, marsh, serp, strain, hand, loli): + for subject in (rf, marsh, serp, strain, hand, loli, k): print subject.__name__ data = subject.serialization_func(test_object, False) assert data['foo'] == TARGET['foo'] @@ -47,3 +47,6 @@ def test_serializers(): assert data['sub']['w'] == TARGET['sub']['w'] assert data['subs'][3]['y'] == TARGET['subs'][3]['y'] assert data['subs'][3]['x'] == TARGET['subs'][3]['x'] + +if __name__ == '__main__': + test_serializers() From 7c23b5d00d26a8b9d505c3e483c0c9e128e96526 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Wed, 12 Apr 2017 14:44:10 -0600 Subject: [PATCH 10/37] Update disscussion docks --- disscussion.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/disscussion.md b/disscussion.md index 6dfe2cb..4ba38b6 100644 --- a/disscussion.md +++ b/disscussion.md @@ -75,6 +75,13 @@ Serialization from python objects to JSON, XML, or other transmission formats is Yes Yes + + kim + Yes + No + Yes + Yes + From 1a2136b382d264e3c03f1b5203b15ae474398cd7 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Wed, 12 Apr 2017 14:50:34 -0600 Subject: [PATCH 11/37] Use many method --- subjects/k.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subjects/k.py b/subjects/k.py index 66a8b64..b4a131e 100644 --- a/subjects/k.py +++ b/subjects/k.py @@ -37,6 +37,6 @@ class ComplexMapper(Mapper): def serialization_func(obj, many): if many: - return [ComplexMapper(obj=x).serialize() for x in obj] + return ComplexMapper.many().serialize(obj) else: return ComplexMapper(obj=obj).serialize() From 2a371083bf3885c4acaf754f9a4f4a7411526428 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Thu, 13 Apr 2017 10:09:55 -0600 Subject: [PATCH 12/37] Adding lima to serialization benchmarks This is going to be suprising I think. It looks like lima might beat even the custom serializers. ping @b6d --- .travis.yml | 2 +- benchmark.py | 10 +++++----- data.py | 2 +- requirements.txt | 1 + subjects/lim.py | 28 ++++++++++++++++++++++++++++ tests/test_serializers.py | 6 +++--- 6 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 subjects/lim.py diff --git a/.travis.yml b/.travis.yml index 1a56f26..586d05e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python python: - - "2.7" + - "3.5" # command to install dependencies install: "pip install -r requirements.txt" # command to run tests diff --git a/benchmark.py b/benchmark.py index bc21a40..9538f80 100644 --- a/benchmark.py +++ b/benchmark.py @@ -2,10 +2,10 @@ from tabulate import tabulate from contextlib import contextmanager -from subjects import (marsh, rf, serp, strain, hand, loli, k) +from subjects import (marsh, rf, serp, strain, hand, loli, k, lim) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, hand, loli, k) +SUBJECTS = (marsh, rf, serp, strain, hand, loli, k, lim) test_object = ParentTestObject() @@ -19,12 +19,12 @@ def timer(tracker): def test_many(func, limit=1000): - for i in xrange(0, limit): + for i in range(0, limit): subject.serialization_func([test_object, test_object], True) def test_one(func, limit=1000): - for i in xrange(0, limit): + for i in range(0, limit): subject.serialization_func(test_object, False) table = [] @@ -42,4 +42,4 @@ def test_one(func, limit=1000): table += [row] table = sorted(table, key=lambda x: x[1] + x[2]) -print tabulate(table, headers=['Library', 'Many Objects', 'One Object',]) +print(tabulate(table, headers=['Library', 'Many Objects (seconds)', 'One Object (seconds)'])) diff --git a/data.py b/data.py index e7aa044..ff11bab 100644 --- a/data.py +++ b/data.py @@ -11,7 +11,7 @@ class ParentTestObject(object): def __init__(self): self.foo = 'bar' self.sub = ChildTestObject() - self.subs = [ChildTestObject(i) for i in xrange(10)] + self.subs = [ChildTestObject(i) for i in range(10)] def bar(self): return 5 diff --git a/requirements.txt b/requirements.txt index e20c1c1..f1ea918 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ pystrainer==1.1.1 tabulate==0.7.7 lollipop==1.1.2 py-kim==1.0.3 +lima==0.5 markdown diff --git a/subjects/lim.py b/subjects/lim.py new file mode 100644 index 0000000..da27a0b --- /dev/null +++ b/subjects/lim.py @@ -0,0 +1,28 @@ +import lima + +__name__ = 'lima' + + +class SubM(lima.Schema): + w = lima.fields.Integer() + x = lima.fields.Integer(get=lambda obj: obj.x + 10) + y = lima.fields.Integer() + z = lima.fields.Integer() + + +class ComplexM(lima.Schema): + foo = lima.fields.String() + bar = lima.fields.Integer(get=lambda obj: obj.bar()) + sub = lima.fields.Embed(schema=SubM) + subs = lima.fields.Embed(schema=SubM, many=True) + + +schema = ComplexM() +many_scheam = ComplexM(many=True) + + +def serialization_func(obj, many): + if many: + return many_scheam.dump(obj) + else: + return schema.dump(obj) diff --git a/tests/test_serializers.py b/tests/test_serializers.py index a7b0a67..65d563b 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,4 +1,4 @@ -from subjects import marsh, rf, serp, strain, hand, loli, k +from subjects import marsh, rf, serp, strain, hand, loli, k, lim from data import ParentTestObject TARGET = { @@ -32,8 +32,8 @@ def test_serializers(): test_object = ParentTestObject() - for subject in (rf, marsh, serp, strain, hand, loli, k): - print subject.__name__ + for subject in (rf, marsh, serp, strain, hand, loli, k, lim): + print(subject.__name__) data = subject.serialization_func(test_object, False) assert data['foo'] == TARGET['foo'] assert data['bar'] == TARGET['bar'] From 517ce5778fe412a703d2b5a412ea7b4a598e858b Mon Sep 17 00:00:00 2001 From: Mike Waites Date: Mon, 17 Apr 2017 08:21:25 +0100 Subject: [PATCH 13/37] Added docker and docker-compose --- Dockerfile | 8 ++++++++ docker-compose.yml | 6 ++++++ requirements.txt | 1 + 3 files changed, 15 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9340b01 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3 + + +ADD . /opt/code +WORKDIR /opt/code/ + +RUN pip install -r requirements.txt +CMD ["python", "benchmark.py"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..be96a80 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +py2: + build: . + command: python benchmark.py + dockerfile: Dockerfile + volumes: + - .:/opt/code diff --git a/requirements.txt b/requirements.txt index f1ea918..d0cbaa2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,6 @@ pystrainer==1.1.1 tabulate==0.7.7 lollipop==1.1.2 py-kim==1.0.3 +git+https://github.com/mikeywaites/kim.git@feature/pipeline-refactor lima==0.5 markdown From d3a403409838df2712861a011b4ee3c6cc4d76d4 Mon Sep 17 00:00:00 2001 From: Jack Saunders Date: Mon, 17 Apr 2017 08:49:28 +0100 Subject: [PATCH 14/37] fix kim requirement, add relative column to output --- benchmark.py | 7 ++++++- requirements.txt | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/benchmark.py b/benchmark.py index 9538f80..cbd51c8 100644 --- a/benchmark.py +++ b/benchmark.py @@ -1,6 +1,7 @@ import time from tabulate import tabulate from contextlib import contextmanager +from decimal import Decimal from subjects import (marsh, rf, serp, strain, hand, loli, k, lim) from data import ParentTestObject @@ -42,4 +43,8 @@ def test_one(func, limit=1000): table += [row] table = sorted(table, key=lambda x: x[1] + x[2]) -print(tabulate(table, headers=['Library', 'Many Objects (seconds)', 'One Object (seconds)'])) +relative_base = min([x[1] + x[2] for x in table]) +for row in table: + result = (row[1] + row[2]) / relative_base + row.append(result) +print(tabulate(table, headers=['Library', 'Many Objects (seconds)', 'One Object (seconds)', 'Relative'])) diff --git a/requirements.txt b/requirements.txt index d0cbaa2..4057365 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,6 @@ pytest pystrainer==1.1.1 tabulate==0.7.7 lollipop==1.1.2 -py-kim==1.0.3 git+https://github.com/mikeywaites/kim.git@feature/pipeline-refactor lima==0.5 markdown From fdb5b6df739a962793e9200a540123991f13bc16 Mon Sep 17 00:00:00 2001 From: Mike Waites Date: Mon, 24 Apr 2017 11:05:58 +0100 Subject: [PATCH 15/37] Kim version 1.1.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4057365..1803571 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,6 @@ pytest pystrainer==1.1.1 tabulate==0.7.7 lollipop==1.1.2 -git+https://github.com/mikeywaites/kim.git@feature/pipeline-refactor +py-kim==1.1.0 lima==0.5 markdown From 5e3c164fa06e93e02af6b522dccfb200585a3764 Mon Sep 17 00:00:00 2001 From: Mike Waites Date: Mon, 24 Apr 2017 11:09:59 +0100 Subject: [PATCH 16/37] Added docs about running tests with Docker. --- README.md | 11 +++++++++++ docker-compose.yml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5734311..e620a5c 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,14 @@ Currently the following projects are benchmarked. * [kim](http://kim.readthedocs.io/en/latest/) Along with a baseline custom function that doesn't use a framework. + + +## Running the test suite + +A Docker container is bundled with the repository which you can use to run the benchmarks. Firstly make sure you have Docker installed. + +1. Install Docker + +2. Build the container `$ docker-compose build` + +3. Run the tests. `$ docker-compose run --rm tests` diff --git a/docker-compose.yml b/docker-compose.yml index be96a80..21ff9bc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -py2: +tests: build: . command: python benchmark.py dockerfile: Dockerfile From 01e0111db9bdd9c1523117694351d2d0f047e86f Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sat, 22 Jul 2017 14:14:54 -0600 Subject: [PATCH 17/37] Updating the serializer benchmark --- requirements.txt | 7 ++++--- subjects/pyd.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 subjects/pyd.py diff --git a/requirements.txt b/requirements.txt index 1803571..c3604e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,12 @@ marshmallow==2.13.4 serpy==0.1.1 -djangorestframework==3.6.2 +djangorestframework==3.6.3 django==1.9 pytest -pystrainer==1.1.1 +pystrainer==1.3.0 tabulate==0.7.7 -lollipop==1.1.2 +lollipop==1.1.5 py-kim==1.1.0 lima==0.5 +pydantic==0.4 markdown diff --git a/subjects/pyd.py b/subjects/pyd.py new file mode 100644 index 0000000..53c4945 --- /dev/null +++ b/subjects/pyd.py @@ -0,0 +1,29 @@ +from datetime import datetime +from pydantic import BaseModel + +__name__ = 'pydantic' + + +class SubM(BaseModel): + w: int = ... + x: int = ... + y: str = ... + z: str = ... + + def __init__(self, *args, **kwargs): + x = kwargs.pop('x', None) + if x: + kwargs['x'] = x + 10 + + return super(SubM, self).__init__(*args, **kwargs) + + +class ComplexM(marshmallow.Schema): + foo: str = ... + bar: int = ... + sub: SubM = ... + subs: List[SubM] = ... + + +def serialization_func(obj, many): + return schema.dump(obj, many=many).data From 4ccb1c02118ae57889746f016ec036acfd20b4ab Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sat, 26 Aug 2017 16:32:48 -0600 Subject: [PATCH 18/37] Adding in toasted marshmallow --- README.md | 1 + benchmark.py | 5 ++--- requirements.txt | 2 +- subjects/tmarsh.py | 29 +++++++++++++++++++++++++++++ tests/test_serializers.py | 4 ++-- 5 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 subjects/tmarsh.py diff --git a/README.md b/README.md index e620a5c..8288738 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Currently the following projects are benchmarked. * [Strainer](https://github.com/voidfiles/strainer) * [Lollipop](http://lollipop.readthedocs.io/en/latest/) * [kim](http://kim.readthedocs.io/en/latest/) +* [toasted-marshmallow](https://github.com/lyft/toasted-marshmallow) Along with a baseline custom function that doesn't use a framework. diff --git a/benchmark.py b/benchmark.py index cbd51c8..66265c6 100644 --- a/benchmark.py +++ b/benchmark.py @@ -1,12 +1,11 @@ import time from tabulate import tabulate from contextlib import contextmanager -from decimal import Decimal -from subjects import (marsh, rf, serp, strain, hand, loli, k, lim) +from subjects import (marsh, rf, serp, strain, hand, loli, k, lim, tmarsh) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, hand, loli, k, lim) +SUBJECTS = (marsh, rf, serp, strain, hand, loli, k, lim, tmarsh) test_object = ParentTestObject() diff --git a/requirements.txt b/requirements.txt index c3604e7..be677ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -marshmallow==2.13.4 +toastedmarshmallow==0.1.0 serpy==0.1.1 djangorestframework==3.6.3 django==1.9 diff --git a/subjects/tmarsh.py b/subjects/tmarsh.py new file mode 100644 index 0000000..3a17563 --- /dev/null +++ b/subjects/tmarsh.py @@ -0,0 +1,29 @@ +import toastedmarshmallow +import marshmallow + +__name__ = 'Taosted Marshmallow' + + +class SubM(marshmallow.Schema): + w = marshmallow.fields.Int() + x = marshmallow.fields.Method('get_x') + y = marshmallow.fields.Str() + z = marshmallow.fields.Int() + + def get_x(self, obj): + return obj.x + 10 + + +class ComplexM(marshmallow.Schema): + foo = marshmallow.fields.Str() + bar = marshmallow.fields.Int() + sub = marshmallow.fields.Nested(SubM) + subs = marshmallow.fields.Nested(SubM, many=True) + + +schema = ComplexM() +schema.jit = toastedmarshmallow.Jit + + +def serialization_func(obj, many): + return schema.dump(obj, many=many).data diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 65d563b..2ae2430 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,4 +1,4 @@ -from subjects import marsh, rf, serp, strain, hand, loli, k, lim +from subjects import marsh, rf, serp, strain, hand, loli, k, lim, tmarsh from data import ParentTestObject TARGET = { @@ -32,7 +32,7 @@ def test_serializers(): test_object = ParentTestObject() - for subject in (rf, marsh, serp, strain, hand, loli, k, lim): + for subject in (rf, marsh, serp, strain, hand, loli, k, lim, tmarsh): print(subject.__name__) data = subject.serialization_func(test_object, False) assert data['foo'] == TARGET['foo'] From f6f5c6bc11d5c06c82cde9416691309f4f7aeec8 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sat, 26 Aug 2017 16:45:47 -0600 Subject: [PATCH 19/37] removing pydantic --- requirements.txt | 1 - subjects/pyd.py | 29 ----------------------------- 2 files changed, 30 deletions(-) delete mode 100644 subjects/pyd.py diff --git a/requirements.txt b/requirements.txt index be677ed..781b994 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,5 +8,4 @@ tabulate==0.7.7 lollipop==1.1.5 py-kim==1.1.0 lima==0.5 -pydantic==0.4 markdown diff --git a/subjects/pyd.py b/subjects/pyd.py deleted file mode 100644 index 53c4945..0000000 --- a/subjects/pyd.py +++ /dev/null @@ -1,29 +0,0 @@ -from datetime import datetime -from pydantic import BaseModel - -__name__ = 'pydantic' - - -class SubM(BaseModel): - w: int = ... - x: int = ... - y: str = ... - z: str = ... - - def __init__(self, *args, **kwargs): - x = kwargs.pop('x', None) - if x: - kwargs['x'] = x + 10 - - return super(SubM, self).__init__(*args, **kwargs) - - -class ComplexM(marshmallow.Schema): - foo: str = ... - bar: int = ... - sub: SubM = ... - subs: List[SubM] = ... - - -def serialization_func(obj, many): - return schema.dump(obj, many=many).data From c77971dc02b5bce9fd5feb0ddac672dabcace661 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sat, 26 Aug 2017 22:54:16 -0600 Subject: [PATCH 20/37] Add in toasted-marsh --- subjects/marsh.py | 2 +- subjects/tmarsh.py | 2 +- tests/test_serializers.py | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/subjects/marsh.py b/subjects/marsh.py index b0ccc17..bd971a9 100644 --- a/subjects/marsh.py +++ b/subjects/marsh.py @@ -14,8 +14,8 @@ def get_x(self, obj): class ComplexM(marshmallow.Schema): - foo = marshmallow.fields.Str() bar = marshmallow.fields.Int() + foo = marshmallow.fields.Str() sub = marshmallow.fields.Nested(SubM) subs = marshmallow.fields.Nested(SubM, many=True) diff --git a/subjects/tmarsh.py b/subjects/tmarsh.py index 3a17563..86aad84 100644 --- a/subjects/tmarsh.py +++ b/subjects/tmarsh.py @@ -1,7 +1,7 @@ import toastedmarshmallow import marshmallow -__name__ = 'Taosted Marshmallow' +__name__ = 'Toasted Marshmallow' class SubM(marshmallow.Schema): diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 2ae2430..aa277db 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,6 +1,6 @@ -from subjects import marsh, rf, serp, strain, hand, loli, k, lim, tmarsh +from subjects import rf, serp, strain, hand, loli, k, lim, tmarsh from data import ParentTestObject - +import pprint TARGET = { 'foo': 'bar', 'bar': 5, @@ -32,9 +32,10 @@ def test_serializers(): test_object = ParentTestObject() - for subject in (rf, marsh, serp, strain, hand, loli, k, lim, tmarsh): + for subject in (rf, tmarsh, serp, strain, hand, loli, k, lim): print(subject.__name__) data = subject.serialization_func(test_object, False) + pprint.pprint(data) assert data['foo'] == TARGET['foo'] assert data['bar'] == TARGET['bar'] assert data['sub']['w'] == TARGET['sub']['w'] From f16cf9f940f7c92530acb01598c46559799f5bf5 Mon Sep 17 00:00:00 2001 From: Siddhartha Date: Fri, 25 May 2018 21:09:43 -0700 Subject: [PATCH 21/37] Add Colander benchmark - add ObjectType type for object serialization - add 'Differential' serializer to handle transformation during serialization - handle callable int via 'Callable' type - compare as strings in test - add sequence schema for 'many' case --- README.md | 1 + benchmark.py | 4 +- requirements.txt | 1 + subjects/col.py | 111 ++++++++++++++++++++++++++++++++++++++ subjects/rf.py | 2 +- tests/test_serializers.py | 22 ++++---- 6 files changed, 127 insertions(+), 14 deletions(-) mode change 100644 => 100755 benchmark.py create mode 100755 subjects/col.py diff --git a/README.md b/README.md index 8288738..6cb737c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Currently the following projects are benchmarked. * [Lollipop](http://lollipop.readthedocs.io/en/latest/) * [kim](http://kim.readthedocs.io/en/latest/) * [toasted-marshmallow](https://github.com/lyft/toasted-marshmallow) +* [Colander](https://docs.pylonsproject.org/projects/colander/en/latest/) Along with a baseline custom function that doesn't use a framework. diff --git a/benchmark.py b/benchmark.py old mode 100644 new mode 100755 index 66265c6..e88eaca --- a/benchmark.py +++ b/benchmark.py @@ -2,10 +2,10 @@ from tabulate import tabulate from contextlib import contextmanager -from subjects import (marsh, rf, serp, strain, hand, loli, k, lim, tmarsh) +from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, hand, loli, k, lim, tmarsh) +SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh) test_object = ParentTestObject() diff --git a/requirements.txt b/requirements.txt index 781b994..9b0c6d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ toastedmarshmallow==0.1.0 serpy==0.1.1 +colander==1.4 djangorestframework==3.6.3 django==1.9 pytest diff --git a/subjects/col.py b/subjects/col.py new file mode 100755 index 0000000..bdf6e9f --- /dev/null +++ b/subjects/col.py @@ -0,0 +1,111 @@ +import colander +from colander import null + +__name__ = 'Colander' + + +class ObjectType(colander.Mapping): + """ + A colander type representing a generic python object + (uses colander mapping-based serialization). + """ + + def serialize(self, node, appstruct): + appstruct = appstruct.__dict__ + return super(ObjectType, self).serialize(node, appstruct) + + def deserialize(self, node, cstruct): + data = super(ObjectType, self).deserialize(node, cstruct) + appstruct = node.instance.__class__() + appstruct.__dict__.update(data) + return appstruct + + +class ObjectSchema(colander.SchemaNode): + schema_type = ObjectType + instance = None + + def serialize(self, appstruct): + if not self.instance: + # set the instance on all child schema nodes as they + # may need to access the instance environment + self.instance = appstruct + for subnode in self.children: + if isinstance(subnode, MethodSchema): + setattr(subnode, 'instance', appstruct) + return super(ObjectSchema, self).serialize(appstruct) + + def deserialize(self, cstruct): + appstruct = super(ObjectSchema, self).deserialize(cstruct) + if not self.instance: + self.instance = appstruct + return appstruct + + +class CallableSchema(colander.SchemaNode): + def serialize(self, appstruct): + if appstruct is null: + return null + appstruct = appstruct() + return super(CallableSchema, self).serialize(appstruct) + + def deserialize(self, cstruct): + if cstruct is null: + return null + appstruct = super(CallableSchema, self).deserialize(cstruct) + return lambda: appstruct + + +class MethodSchema(CallableSchema): + def serialize(self, appstruct): + if appstruct is null: + appstruct = getattr(self.instance, self.name) + return super(MethodSchema, self).serialize(appstruct) + + +class Differential(colander.SchemaNode): + def __init__(self, typ, differential=0): + self.differential = differential + super(Differential, self).__init__(typ) + + def serialize(self, appstruct): + # operator could be overloaded by the appstruct class if necessary + appstruct += self.differential + return super(Differential, self).serialize(appstruct) + + def deserialize(self, cstruct): + # operator could be overloaded by the appstruct class if necessary + appstruct = super(Differential, self).deserialize(cstruct) + appstruct -= self.differential + return appstruct + + +class ChildSchema(ObjectSchema): + w = colander.SchemaNode(colander.Int()) + y = colander.SchemaNode(colander.String()) + x = Differential(colander.Int(), 10) + z = colander.SchemaNode(colander.Int()) + + +class ChildListSchema(colander.SequenceSchema): + sub = ChildSchema() + + +class ParentSchema(ObjectSchema): + foo = colander.SchemaNode(colander.String()) + bar = MethodSchema(colander.Int()) + sub = ChildSchema() + subs = ChildListSchema() + + +class ParentListSchema(colander.SequenceSchema): + parents = ParentSchema() + + +unit_schema = ParentSchema() +seq_schema = ParentListSchema() + + +def serialization_func(obj, many): + schema = seq_schema if many else unit_schema + return schema.serialize(obj) diff --git a/subjects/rf.py b/subjects/rf.py index 19027d0..bae0bf2 100644 --- a/subjects/rf.py +++ b/subjects/rf.py @@ -10,7 +10,7 @@ class SubRF(rf_serializers.Serializer): - w = rf_serializers.FloatField() + w = rf_serializers.IntegerField() x = rf_serializers.SerializerMethodField() y = rf_serializers.CharField() z = rf_serializers.IntegerField() diff --git a/tests/test_serializers.py b/tests/test_serializers.py index aa277db..1b8016a 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,4 +1,4 @@ -from subjects import rf, serp, strain, hand, loli, k, lim, tmarsh +from subjects import rf, serp, strain, col, hand, loli, k, lim, tmarsh from data import ParentTestObject import pprint TARGET = { @@ -32,22 +32,22 @@ def test_serializers(): test_object = ParentTestObject() - for subject in (rf, tmarsh, serp, strain, hand, loli, k, lim): + for subject in (rf, tmarsh, serp, strain, col, hand, loli, k, lim): print(subject.__name__) data = subject.serialization_func(test_object, False) pprint.pprint(data) - assert data['foo'] == TARGET['foo'] - assert data['bar'] == TARGET['bar'] - assert data['sub']['w'] == TARGET['sub']['w'] - assert data['subs'][3]['y'] == TARGET['subs'][3]['y'] - assert data['subs'][3]['x'] == TARGET['subs'][3]['x'] + assert str(data['foo']) == str(TARGET['foo']) + assert str(data['bar']) == str(TARGET['bar']) + assert str(data['sub']['w']) == str(TARGET['sub']['w']) + assert str(data['subs'][3]['y']) == str(TARGET['subs'][3]['y']) + assert str(data['subs'][3]['x']) == str(TARGET['subs'][3]['x']) datas = subject.serialization_func([test_object, test_object], True) for data in datas: - assert data['foo'] == TARGET['foo'] - assert data['sub']['w'] == TARGET['sub']['w'] - assert data['subs'][3]['y'] == TARGET['subs'][3]['y'] - assert data['subs'][3]['x'] == TARGET['subs'][3]['x'] + assert str(data['foo']) == str(TARGET['foo']) + assert str(data['sub']['w']) == str(TARGET['sub']['w']) + assert str(data['subs'][3]['y']) == str(TARGET['subs'][3]['y']) + assert str(data['subs'][3]['x']) == str(TARGET['subs'][3]['x']) if __name__ == '__main__': test_serializers() From 22024be5ebad07b6d1e0d8f013cdfa497687e414 Mon Sep 17 00:00:00 2001 From: voidfiles Date: Mon, 2 Jul 2018 16:26:33 -0600 Subject: [PATCH 22/37] fix deploy --- deploy.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deploy.sh b/deploy.sh index 1965fda..6430901 100755 --- a/deploy.sh +++ b/deploy.sh @@ -53,5 +53,8 @@ chmod 600 deploy_key eval `ssh-agent -s` ssh-add deploy_key +rm -fR __pycache__ +rm -fR subjects/__pycache__ + # Now that we're all set up, we can push. git push $SSH_REPO $TARGET_BRANCH From 39db7b25996c4424ed9a910628944af7059b70bc Mon Sep 17 00:00:00 2001 From: Hugo Klepsch Date: Tue, 14 May 2019 12:02:04 -0400 Subject: [PATCH 23/37] Add avro benchmark --- benchmark.py | 4 +-- requirements.txt | 1 + subjects/avro.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 subjects/avro.py diff --git a/benchmark.py b/benchmark.py index e88eaca..05684e1 100755 --- a/benchmark.py +++ b/benchmark.py @@ -2,10 +2,10 @@ from tabulate import tabulate from contextlib import contextmanager -from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh) +from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh) +SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro) test_object = ParentTestObject() diff --git a/requirements.txt b/requirements.txt index 9b0c6d7..63a00d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ lollipop==1.1.5 py-kim==1.1.0 lima==0.5 markdown +avro-python3==1.8.2 \ No newline at end of file diff --git a/subjects/avro.py b/subjects/avro.py new file mode 100644 index 0000000..2bb5d96 --- /dev/null +++ b/subjects/avro.py @@ -0,0 +1,74 @@ +import avro.schema +from avro.io import DatumWriter + +__name__ = 'Avro' + +class NullWriter(object): + def write(self, *args, **kwargs): + pass + + def write_utf8(self, *args, **kwargs): + self.write(args, kwargs) + + def write_int(self, *args, **kwargs): + self.write(args, kwargs) + + def write_long(self, *args, **kwargs): + self.write(args, kwargs) + +schema_name_tracker = avro.schema.Names() + +child_test_object_schema = avro.schema.SchemaFromJSONData({ + "namespace": "benchmark.avro", + "type": "record", + "name": "childTestObject", + "fields": [ + {"name": "w", "type": "int"}, + {"name": "x", "type": "int"}, + {"name": "y", "type": "string"}, + {"name": "z", "type": "int"} + ] +}, names=schema_name_tracker) + +parent_test_object_schema = avro.schema.SchemaFromJSONData({ + "namespace": "benchmark.avro", + "type": "record", + "name": "parentTestObject", + "fields": [ + {"name": "foo", "type": "string"}, + {"name": "sub", "type": "childTestObject"}, + { + "name": "subs", + "type": { + "type": "array", + "items": "childTestObject" + } + } + ] +}, names=schema_name_tracker) + +datum_writer = DatumWriter(writer_schema=parent_test_object_schema) +null_binary_writer = NullWriter() + +# Avro for Python can't directly serialize a class, it must be a dictionary. +def nested_class_to_dict(obj): + if not hasattr(obj,"__dict__"): + return obj + result = {} + for key, val in obj.__dict__.items(): + if key.startswith("_"): + continue + element = [] + if isinstance(val, list): + for item in val: + element.append(nested_class_to_dict(item)) + else: + element = nested_class_to_dict(val) + result[key] = element + return result + +def serialization_func(to_serialize, many): + if many: + return [datum_writer.write(nested_class_to_dict(obj), null_binary_writer) for obj in to_serialize] + else: + return datum_writer.write(nested_class_to_dict(to_serialize), null_binary_writer) From f5c4281ea2650f5e99d473df5ef50380310307f6 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 10:46:22 -0600 Subject: [PATCH 24/37] Update deploy key --- .travis.yml | 13 +++++++------ deploy-key.enc | Bin 0 -> 3392 bytes deploy_key.enc | Bin 3248 -> 0 bytes 3 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 deploy-key.enc delete mode 100644 deploy_key.enc diff --git a/.travis.yml b/.travis.yml index 586d05e..e05078c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,7 @@ language: python python: - - "3.5" -# command to install dependencies -install: "pip install -r requirements.txt" -# command to run tests +- '3.5' +install: pip install -r requirements.txt script: py.test deploy: provider: script @@ -12,5 +10,8 @@ deploy: branch: master env: global: - - ENCRYPTION_LABEL: "3e8c259749ef" - - COMMIT_AUTHOR_EMAIL: "voidfiles@gmail.com" + - ENCRYPTION_LABEL: 3e8c259749ef + - COMMIT_AUTHOR_EMAIL: voidfiles@gmail.com +before_install: +- openssl aes-256-cbc -K $encrypted_1dbde6ec09a5_key -iv $encrypted_1dbde6ec09a5_iv + -in deploy-key.enc -out deploy-key -d diff --git a/deploy-key.enc b/deploy-key.enc new file mode 100644 index 0000000000000000000000000000000000000000..4c226d265a17c914dca0f975e1274061a69a017d GIT binary patch literal 3392 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 From 5bdf5831753f7ea657745fbc7b5484f87cdc3e22 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 10:50:41 -0600 Subject: [PATCH 25/37] Update deploy script --- deploy.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy.sh b/deploy.sh index 6430901..40dbb59 100755 --- a/deploy.sh +++ b/deploy.sh @@ -48,10 +48,10 @@ ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key" ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv" ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR} ENCRYPTED_IV=${!ENCRYPTED_IV_VAR} -openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in ../deploy_key.enc -out deploy_key -d -chmod 600 deploy_key +openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in ../deploy-key.enc -out deploy-key -d +chmod 600 deploy-key eval `ssh-agent -s` -ssh-add deploy_key +ssh-add deploy-key rm -fR __pycache__ rm -fR subjects/__pycache__ From 6cdf6a5b0de3e37e0ff570a34a2d0d5ae1d740f3 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 10:58:48 -0600 Subject: [PATCH 26/37] Update toastedmarshmallow --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 63a00d3..5ddde78 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -toastedmarshmallow==0.1.0 +toastedmarshmallow==2.15.2.post1 serpy==0.1.1 colander==1.4 djangorestframework==3.6.3 @@ -10,4 +10,4 @@ lollipop==1.1.5 py-kim==1.1.0 lima==0.5 markdown -avro-python3==1.8.2 \ No newline at end of file +avro-python3==1.8.2 From f6ff942461c5c787745f79a100f145d6bcaf98c9 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 11:02:08 -0600 Subject: [PATCH 27/37] Update serpy --- .travis.yml | 1 - deploy.sh | 5 ----- requirements.txt | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index e05078c..b05690f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,6 @@ deploy: branch: master env: global: - - ENCRYPTION_LABEL: 3e8c259749ef - COMMIT_AUTHOR_EMAIL: voidfiles@gmail.com before_install: - openssl aes-256-cbc -K $encrypted_1dbde6ec09a5_key -iv $encrypted_1dbde6ec09a5_iv diff --git a/deploy.sh b/deploy.sh index 40dbb59..f778011 100755 --- a/deploy.sh +++ b/deploy.sh @@ -44,11 +44,6 @@ git add . git commit -m "Deploy to GitHub Pages: ${SHA}" # Get the deploy key by using Travis's stored variables to decrypt deploy_key.enc -ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key" -ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv" -ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR} -ENCRYPTED_IV=${!ENCRYPTED_IV_VAR} -openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in ../deploy-key.enc -out deploy-key -d chmod 600 deploy-key eval `ssh-agent -s` ssh-add deploy-key diff --git a/requirements.txt b/requirements.txt index 5ddde78..823f8a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ toastedmarshmallow==2.15.2.post1 -serpy==0.1.1 +serpy==0.3.1 colander==1.4 djangorestframework==3.6.3 django==1.9 From 1e91c5d5eb343a2260963927e03a34ed74e8a958 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 11:03:37 -0600 Subject: [PATCH 28/37] Update colander --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 823f8a6..4b87551 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ toastedmarshmallow==2.15.2.post1 serpy==0.3.1 -colander==1.4 +colander==1.7.0 djangorestframework==3.6.3 django==1.9 pytest From 774c5ef1fca7ee41b90b10dccc0323b13ffc5e20 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 11:06:01 -0600 Subject: [PATCH 29/37] Update lollipop --- .travis.yml | 4 +--- deploy.sh | 5 +++++ requirements.txt | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b05690f..9d44686 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,5 @@ deploy: branch: master env: global: + - ENCRYPTION_LABEL: 1dbde6ec09a5 - COMMIT_AUTHOR_EMAIL: voidfiles@gmail.com -before_install: -- openssl aes-256-cbc -K $encrypted_1dbde6ec09a5_key -iv $encrypted_1dbde6ec09a5_iv - -in deploy-key.enc -out deploy-key -d diff --git a/deploy.sh b/deploy.sh index f778011..40dbb59 100755 --- a/deploy.sh +++ b/deploy.sh @@ -44,6 +44,11 @@ git add . git commit -m "Deploy to GitHub Pages: ${SHA}" # Get the deploy key by using Travis's stored variables to decrypt deploy_key.enc +ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key" +ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv" +ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR} +ENCRYPTED_IV=${!ENCRYPTED_IV_VAR} +openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in ../deploy-key.enc -out deploy-key -d chmod 600 deploy-key eval `ssh-agent -s` ssh-add deploy-key diff --git a/requirements.txt b/requirements.txt index 4b87551..a086818 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ django==1.9 pytest pystrainer==1.3.0 tabulate==0.7.7 -lollipop==1.1.5 +lollipop==1.1.7 py-kim==1.1.0 lima==0.5 markdown From 4e097aaaab0e4f1ac98fd7737a404cc192a6b807 Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 11:07:32 -0600 Subject: [PATCH 30/37] Update pykim --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a086818..8158dbe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ pytest pystrainer==1.3.0 tabulate==0.7.7 lollipop==1.1.7 -py-kim==1.1.0 +py-kim==1.2.2 lima==0.5 markdown avro-python3==1.8.2 From 632dd64e1b07462050d61728f8e236b64edf314e Mon Sep 17 00:00:00 2001 From: Alex Kessinger Date: Sun, 7 Jul 2019 11:10:22 -0600 Subject: [PATCH 31/37] Update DRF and django --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8158dbe..25ec10f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ toastedmarshmallow==2.15.2.post1 serpy==0.3.1 colander==1.7.0 -djangorestframework==3.6.3 -django==1.9 +djangorestframework==3.9.4 +django==2.2 pytest pystrainer==1.3.0 tabulate==0.7.7 From 1a93546aa72707b18ccdab136a19b71b9f27a87f Mon Sep 17 00:00:00 2001 From: rtkhklepsch <38769588+rtkhklepsch@users.noreply.github.com> Date: Sun, 7 Jul 2019 13:13:39 -0400 Subject: [PATCH 32/37] Add Python pickle benchmark (#10) --- benchmark.py | 4 ++-- subjects/pickle.py | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 subjects/pickle.py diff --git a/benchmark.py b/benchmark.py index 05684e1..2d57d82 100755 --- a/benchmark.py +++ b/benchmark.py @@ -2,10 +2,10 @@ from tabulate import tabulate from contextlib import contextmanager -from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro) +from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro, pickle) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro) +SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro, pickle) test_object = ParentTestObject() diff --git a/subjects/pickle.py b/subjects/pickle.py new file mode 100644 index 0000000..f017d82 --- /dev/null +++ b/subjects/pickle.py @@ -0,0 +1,7 @@ +import pickle + +__name__ = 'Pickle' + + +def serialization_func(obj, many): + return pickle.dumps(obj) From ee599b910432b5042e6b8c7aed5da7eee71a12de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2020 00:08:05 -0700 Subject: [PATCH 33/37] Bump django from 2.2 to 2.2.8 (#14) Bumps [django](https://github.com/django/django) from 2.2 to 2.2.8. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/2.2...2.2.8) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 25ec10f..3ce1bd1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ toastedmarshmallow==2.15.2.post1 serpy==0.3.1 colander==1.7.0 djangorestframework==3.9.4 -django==2.2 +django==2.2.8 pytest pystrainer==1.3.0 tabulate==0.7.7 From 8bde08d92f76e193a2c60cdbd37cc1e46bc271de Mon Sep 17 00:00:00 2001 From: Antti Jokipii Date: Mon, 27 Apr 2020 18:39:58 +0300 Subject: [PATCH 34/37] Documentation update (#15) --- README.md | 8 +++++--- disscussion.md | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6cb737c..a1693c1 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,16 @@ You can find the latest benchmarks on [this page](https://voidfiles.github.io/py Currently the following projects are benchmarked. -* [Django REST framework](http://www.django-rest-framework.org/) +* [Django REST Framework](http://www.django-rest-framework.org/) * [serpy](http://serpy.readthedocs.io/) * [Marshmallow](https://marshmallow.readthedocs.io/en/latest/) * [Strainer](https://github.com/voidfiles/strainer) * [Lollipop](http://lollipop.readthedocs.io/en/latest/) -* [kim](http://kim.readthedocs.io/en/latest/) -* [toasted-marshmallow](https://github.com/lyft/toasted-marshmallow) +* [Kim](http://kim.readthedocs.io/en/latest/) +* [Toasted Marshmallow](https://github.com/lyft/toasted-marshmallow) * [Colander](https://docs.pylonsproject.org/projects/colander/en/latest/) +* [Lima](https://github.com/b6d/lima/) +* [Avro](https://avro.apache.org/) Along with a baseline custom function that doesn't use a framework. diff --git a/disscussion.md b/disscussion.md index 4ba38b6..d378e8f 100644 --- a/disscussion.md +++ b/disscussion.md @@ -55,7 +55,7 @@ Serialization from python objects to JSON, XML, or other transmission formats is No - marshmallow + Marshmallow Yes Yes Yes @@ -69,19 +69,47 @@ Serialization from python objects to JSON, XML, or other transmission formats is Yes - strainer + Strainer Yes - Yes + No Yes Yes - kim + Kim Yes No Yes Yes + + Toasted Marshmallow + Yes + Yes + Yes + Yes + + + Colander + Yes + No + Yes< + Yes + + + Lima + Yes + No + No + No + + + Avro + Yes + Yes + Yes + No + From 6cbba2c05842b39304906e1e91458f9894c067fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2020 09:40:14 -0600 Subject: [PATCH 35/37] Bump django from 2.2.8 to 2.2.10 (#16) Bumps [django](https://github.com/django/django) from 2.2.8 to 2.2.10. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/2.2.8...2.2.10) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3ce1bd1..562313d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ toastedmarshmallow==2.15.2.post1 serpy==0.3.1 colander==1.7.0 djangorestframework==3.9.4 -django==2.2.8 +django==2.2.10 pytest pystrainer==1.3.0 tabulate==0.7.7 From d8452fa880756746f1fe874aa24953dda7af01a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Grignard?= <51887114+grignards@users.noreply.github.com> Date: Tue, 5 Jan 2021 05:17:53 +0100 Subject: [PATCH 36/37] Add serpyco to benchmark (#17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add serpyco to subjects * Update CI python version to 3.6 Co-authored-by: Sébastien Grignard Co-authored-by: Alex Kessinger --- .travis.yml | 2 +- README.md | 1 + benchmark.py | 6 +++--- disscussion.md | 7 +++++++ requirements.txt | 1 + subjects/avro.py | 2 +- subjects/col.py | 2 +- subjects/hand.py | 2 +- subjects/k.py | 2 +- subjects/lim.py | 2 +- subjects/loli.py | 2 +- subjects/marsh.py | 2 +- subjects/pickle.py | 2 +- subjects/rf.py | 2 +- subjects/serp.py | 2 +- subjects/serpy.py | 35 +++++++++++++++++++++++++++++++++++ subjects/strain.py | 2 +- subjects/tmarsh.py | 2 +- 18 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 subjects/serpy.py diff --git a/.travis.yml b/.travis.yml index 9d44686..bb38d26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python python: -- '3.5' +- '3.6' install: pip install -r requirements.txt script: py.test deploy: diff --git a/README.md b/README.md index a1693c1..34eefc2 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Currently the following projects are benchmarked. * [Toasted Marshmallow](https://github.com/lyft/toasted-marshmallow) * [Colander](https://docs.pylonsproject.org/projects/colander/en/latest/) * [Lima](https://github.com/b6d/lima/) +- [Serpyco](https://gitlab.com/sgrignard/serpyco) * [Avro](https://avro.apache.org/) Along with a baseline custom function that doesn't use a framework. diff --git a/benchmark.py b/benchmark.py index 2d57d82..c757131 100755 --- a/benchmark.py +++ b/benchmark.py @@ -2,10 +2,10 @@ from tabulate import tabulate from contextlib import contextmanager -from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro, pickle) +from subjects import (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro, pickle, serpy) from data import ParentTestObject -SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro, pickle) +SUBJECTS = (marsh, rf, serp, strain, col, hand, loli, k, lim, tmarsh, avro, pickle, serpy) test_object = ParentTestObject() @@ -29,7 +29,7 @@ def test_one(func, limit=1000): table = [] for subject in SUBJECTS: - row = [subject.__name__] + row = [subject.name] test_many(subject.serialization_func, 2) # Warmup with timer(row): diff --git a/disscussion.md b/disscussion.md index d378e8f..1494574 100644 --- a/disscussion.md +++ b/disscussion.md @@ -82,6 +82,13 @@ Serialization from python objects to JSON, XML, or other transmission formats is Yes Yes + + serpyco + Yes + Yes + Yes + Yes + Toasted Marshmallow Yes diff --git a/requirements.txt b/requirements.txt index 562313d..4fb0221 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ py-kim==1.2.2 lima==0.5 markdown avro-python3==1.8.2 +serpyco==1.1.0 \ No newline at end of file diff --git a/subjects/avro.py b/subjects/avro.py index 2bb5d96..fe797b2 100644 --- a/subjects/avro.py +++ b/subjects/avro.py @@ -1,7 +1,7 @@ import avro.schema from avro.io import DatumWriter -__name__ = 'Avro' +name = 'Avro' class NullWriter(object): def write(self, *args, **kwargs): diff --git a/subjects/col.py b/subjects/col.py index bdf6e9f..fe2e3b5 100755 --- a/subjects/col.py +++ b/subjects/col.py @@ -1,7 +1,7 @@ import colander from colander import null -__name__ = 'Colander' +name = 'Colander' class ObjectType(colander.Mapping): diff --git a/subjects/hand.py b/subjects/hand.py index 15788bd..8e29b8e 100644 --- a/subjects/hand.py +++ b/subjects/hand.py @@ -1,4 +1,4 @@ -__name__ = 'Custom' +name = 'Custom' def sub_to_cstruct(obj): diff --git a/subjects/k.py b/subjects/k.py index b4a131e..7e49c89 100644 --- a/subjects/k.py +++ b/subjects/k.py @@ -1,6 +1,6 @@ from kim import Mapper, field -__name__ = 'kim' +name = 'kim' class Complex(object): diff --git a/subjects/lim.py b/subjects/lim.py index da27a0b..4061d9f 100644 --- a/subjects/lim.py +++ b/subjects/lim.py @@ -1,6 +1,6 @@ import lima -__name__ = 'lima' +name = 'lima' class SubM(lima.Schema): diff --git a/subjects/loli.py b/subjects/loli.py index e230409..1c2e247 100644 --- a/subjects/loli.py +++ b/subjects/loli.py @@ -1,7 +1,7 @@ from collections import namedtuple from lollipop.types import Object, String, Integer, List, FunctionField, MethodField -__name__ = 'Lollipop' +name = 'Lollipop' SubS = namedtuple('SubS', ['w', 'x', 'y', 'z']) ComplexS = namedtuple('ComplexS', ['foo', 'bar', 'sub', 'subs']) diff --git a/subjects/marsh.py b/subjects/marsh.py index bd971a9..34112ff 100644 --- a/subjects/marsh.py +++ b/subjects/marsh.py @@ -1,6 +1,6 @@ import marshmallow -__name__ = 'Marshmallow' +name = 'Marshmallow' class SubM(marshmallow.Schema): diff --git a/subjects/pickle.py b/subjects/pickle.py index f017d82..b67a780 100644 --- a/subjects/pickle.py +++ b/subjects/pickle.py @@ -1,6 +1,6 @@ import pickle -__name__ = 'Pickle' +name = 'Pickle' def serialization_func(obj, many): diff --git a/subjects/rf.py b/subjects/rf.py index bae0bf2..5c36cbc 100644 --- a/subjects/rf.py +++ b/subjects/rf.py @@ -6,7 +6,7 @@ from rest_framework import serializers as rf_serializers -__name__ = 'Django REST Framework' +name = 'Django REST Framework' class SubRF(rf_serializers.Serializer): diff --git a/subjects/serp.py b/subjects/serp.py index 3aa60b0..28f5668 100644 --- a/subjects/serp.py +++ b/subjects/serp.py @@ -1,6 +1,6 @@ import serpy -__name__ = 'serpy' +name = 'serpy' class SubS(serpy.Serializer): diff --git a/subjects/serpy.py b/subjects/serpy.py new file mode 100644 index 0000000..66511f9 --- /dev/null +++ b/subjects/serpy.py @@ -0,0 +1,35 @@ +import dataclasses +import typing + +import serpyco + +from data import ParentTestObject + +name = "serpyco" + + +def get_x(obj): + return obj.x + 10 + + +@dataclasses.dataclass +class SubM: + w: int + y: str + z: int + x: int = serpyco.field(getter=get_x) + + +@dataclasses.dataclass +class ComplexM: + foo: str + sub: SubM + subs: typing.List[SubM] + bar: int = serpyco.field(getter=ParentTestObject.bar) + + +serializer = serpyco.Serializer(ComplexM) + + +def serialization_func(obj, many): + return serializer.dump(obj, many=many) diff --git a/subjects/strain.py b/subjects/strain.py index 1183e40..922799a 100644 --- a/subjects/strain.py +++ b/subjects/strain.py @@ -1,6 +1,6 @@ import strainer -__name__ = 'Strainer' +name = 'Strainer' sub_strainer_serializer = strainer.serializer( strainer.field('w'), diff --git a/subjects/tmarsh.py b/subjects/tmarsh.py index 86aad84..39d44cd 100644 --- a/subjects/tmarsh.py +++ b/subjects/tmarsh.py @@ -1,7 +1,7 @@ import toastedmarshmallow import marshmallow -__name__ = 'Toasted Marshmallow' +name = 'Toasted Marshmallow' class SubM(marshmallow.Schema): From b45cb024a553e78a81e1a8c5a3056b7b9100baab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Feb 2021 15:48:09 -0700 Subject: [PATCH 37/37] Bump django from 2.2.10 to 2.2.13 (#18) Bumps [django](https://github.com/django/django) from 2.2.10 to 2.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/2.2.10...2.2.13) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4fb0221..8d71761 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ toastedmarshmallow==2.15.2.post1 serpy==0.3.1 colander==1.7.0 djangorestframework==3.9.4 -django==2.2.10 +django==2.2.13 pytest pystrainer==1.3.0 tabulate==0.7.7