]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - doc/performance.rst
New performance measurements
[pyderasn.git] / doc / performance.rst
diff --git a/doc/performance.rst b/doc/performance.rst
new file mode 100644 (file)
index 0000000..d044c3e
--- /dev/null
@@ -0,0 +1,145 @@
+.. _performance:
+
+Performance
+===========
+
+.. contents::
+
+Performance is compared between ``pyderasn==6.1``, ``pyasn1==0.4.8`` and
+``asn1crypto==1.3.0``. Decode CACert.org's CRL (2019-02-08 state, 8.72
+MiB), encode it, pickle decoded structure and unpickle it. Machine is
+Intel Core i5-6200U 2.3 GHz, 8 GB RAM, FreeBSD 12.0 amd64, Python 2.7.15
+and Python 3.6.6 from native FreeBSD ports.
+
+Code
+----
+
+pyasn1::
+
+    from pyasn1.codec.der.decoder import decode as der_decoder
+    from pyasn1.codec.der.encoder import encode as der_encoder
+    from pyasn1_modules.rfc5280 import CertificateList
+    with open("revoke.crl", "rb") as fd:
+        raw = fd.read()
+    start = time()
+    crl, _ = der_decoder(raw, asn1Spec=CertificateList())
+    print("decode", time() - start)
+    del raw
+    gc.collect()
+    start = time()
+    der_encoder(c)
+    print("encode", time() - start)
+    # pyasn1 objects are not picklable
+
+asn1crypto::
+
+    from asn1crypto.crl import CertificateList
+    with open("revoke.crl", "rb") as fd:
+        raw = fd.read()
+    start = time()
+    crl = CertificateList.load(raw)
+    c.native  # full decoding and Python representation requires that
+    print("decode", time() - start)
+    del raw
+    gc.collect()
+    start = time()
+    crl.dump(force=True)  # forced DER encoding
+    print("encode", time() - start)
+    start = time()
+    raw = pickle.dumps(crl)
+    print("dumps", time() - start)
+    del crl
+    gc.collect()
+    print(len(raw))
+    start = time()
+    pickle.loads(raw)
+    print("loads", time() - start)
+
+pyderasn::
+
+    from tests.test_crl import CertificateList
+    with open("revoke.crl", "rb") as fd:
+        raw = fd.read()
+    start = time()
+    crl = CertificateList().decod(raw)
+    print("decode", time() - start)
+    del raw
+    gc.collect()
+    start = time()
+    crl.encode()
+    print("encode", time() - start)
+    start = time()
+    raw = pickle.dumps(crl)
+    print("dumps", time() - start)
+    del crl
+    gc.collect()
+    print(len(raw))
+    start = time()
+    pickle.loads(raw)
+    print("loads", time() - start)
+
+Also there are `cythonized <https://cython.org/>`__ asn1crypto and
+pyderasn versions, made using ``Cython==0.29.14``,
+``FreeBSD clang version 6.0.1 (tags/RELEASE_601/final 335540) (based on
+LLVM 6.0.1)``, ``CFLAGS=-O2`` and Python 3 mode.
+
+DER
+---
+
+.. list-table::
+   :header-rows: 1
+
+   * - Library
+     - Decode time, sec (Py36/Py27)
+     - Encode time, sec (Py36/Py27)
+     - Memory used, MiB (Py36/Py27)
+   * - pyasn1
+     - 1353 / 1400
+     - 37.5 / 36.7
+     - 1645 / 3296
+   * - asn1crypto
+     - 27.5 / 38
+     - 25.7 / 28
+     - 876 / 1742
+   * - cython asn1crypto
+     - 15.6 / N/A
+     - 15.8 / N/A
+     - 880 / N/A
+   * - pyderasn
+     - 33.2 / 33.4
+     - 7.6 / 7.4
+     - 560 / 516
+   * - cython pyderasn
+     - 23 / N/A
+     - 5.9 / N/A
+     - 561 / N/A
+
+asn1crypto performs slightly better (with higher memory cost), but pay
+attention that it contains **much** less data for all objects (like
+offsets, sizes, etc) and it is not strict at all, passing possibly
+invalid DER structures! Also there are plenty of other :ref:`features`
+it lacks.
+
+pickle
+------
+
+pyasn1 objects are not pickable.
+
+.. list-table::
+   :header-rows: 1
+
+   * - Library
+     - dumps time, sec (Py36/Py27)
+     - loads time, sec (Py36/Py27)
+     - Memory used, MiB (Py36/Py27)
+     - Size, MiB (Py36/Py27)
+   * - asn1crypto
+     - 7.9 / 145
+     - 8.3 / 91.4
+     - 2474 / 4944
+     - 174.8 / 373
+   * - pyderasn
+     - 82 / 244
+     - 17 / 77.8
+     - 3010 / 4372
+     - 110.5 / 248.6