Performance

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 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

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 Features it lacks.

pickle

pyasn1 objects are not pickable.

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