asn1c
asn1c copied to clipboard
Encoding performance of DER and XER
This is not really a bug report, but more of a question regarding performance. (Honestly, I suspect a bug in my own code, but insofar have been unable to find it.)
I'm trying to evaluate a certain ASN.1 schema using asn1c. I've written a simple test that measures the time needed to encode a bunch of messages in memory, and I find it strange that XER encoding outperforms DER encoding by roughly a factor of 2. Is such a result expected?
Here's the code doing the measurement.
// byte consumer func
print2fp(const void *buffer, size_t size, void *app_key) {
FILE *stream = (FILE *)app_key;
if (fwrite(buffer, 1, size, stream) != size)
return -1;
return 0;
}
// utility for measuring time
long double duration(const struct timeval *start, const struct timeval *stop) {
return (long double)(stop->tv_usec - start->tv_usec) / 1000000 + (long double)(stop->tv_sec - start->tv_sec);
}
Each code snippet gets the following variables
struct timeval start, stop;
long double total = 0.0;
char buff[200];
size_t errSize = sizeof(buff);
size_t encodedSize;
size_t iterations = 100000;
FILE *dev_null = fopen("/dev/null", "w");
DER encoding
for (uint64_t i = 0; i < iterations; i++) {
asn_enc_rval_t ec;
gettimeofday(&start, NULL);
// could also invoke with der_encode(&asn_DEF_Message, message, NULL, NULL)
// but the same does not work with xer_encode, so I'm using /dev/null
ec = der_encode(&asn_DEF_Message, message, print2fp, dev_null);
gettimeofday(&stop, NULL);
assert(ec.encoded != -1);
assert(asn_check_constraints(&asn_DEF_Message, message, buff, &errSize) == 0);
encodedSize = ec.encoded;
total += duration(&start, &stop);
}
XER encoding:
for (uint64_t i = 0; i < iterations; i++) {
asn_enc_rval_t ec;
gettimeofday(&start, NULL);
// invoking xer_encode(&asn_DEF_Message, message, XER_F_BASIC, NULL, NULL) segfaults,
// because the function for consuming bytes (set to `NULL`) is being dereferenced,
// so I use /dev/null, instead
ec = xer_encode(&asn_DEF_Message, message, XER_F_BASIC, print2fp, dev_null);
gettimeofday(&stop, NULL);
assert(ec.encoded != -1);
assert(asn_check_constraints(&asn_DEF_Message, message, buff, &errSize) == 0);
encodedSize = ec.encoded;
total += duration(&start, &stop);
}
Running these two functions on a series of messages I consistently get that encoding DER is about a factor of 2 slower than XER. I find this surprising, since in the analog decoding example, DER consistently outperforms XER.
How fast is BER encoding? DER is usually used in cryptographic operations where performance is less important.