Feature #4309


[ext/openssl] ASN1 performance enhancement

Added by MartinBosslet (Martin Bosslet) over 11 years ago. Updated about 11 years ago.

Target version:


Hi all,

recently I noticed that the method

static int ossl_asn1_default_tag(VALUE obj)

(in ossl_asn1.c) iterates through an internal array each time a default tag is to be looked up resulting in O(n) runtime
performance. I thought this to be the ideal situation for using a hash and so I added one with OpenSSL::ASN1Data subclasses
acting as keys and the corresponding tags as values. I also did some profiling to see whether the constant lookup time made
some impact. I first ran a test encoding and parsing a certificate a couple of times and that's what I got:

Old code:
1.998611 seconds.
2.004065 seconds.
1.981882 seconds.
2.129491 seconds.
1.953846 seconds.
1.957313 seconds.
1.958523 seconds.
1.976004 seconds.
1.925835 seconds.
1.974381 seconds.

New code:
1.886169 seconds.
1.871291 seconds.
1.829164 seconds.
1.927687 seconds.
1.879508 seconds.
1.848399 seconds.
1.942286 seconds.
1.908133 seconds.
1.839384 seconds.
1.861159 seconds.

Not much, but I think the improvement is noticeable. Next I ran a "worst case scenario" for the old code.
I encoded and decoded a Sequence with 4 BMPString values, since BMPString with tag 30 is at the end of
the internal array. Here the performance gain was roughly 15%:

Old code worst case:
1.507455 seconds.
1.503871 seconds.
1.563551 seconds.
1.523261 seconds.
1.564125 seconds.
1.526295 seconds.
1.553073 seconds.
1.877483 seconds.
1.543568 seconds.
1.518273 seconds.

New code worst case:
1.347785 seconds.
1.359214 seconds.
1.389248 seconds.
1.466773 seconds.
1.350079 seconds.
1.406290 seconds.
1.393683 seconds.
1.368601 seconds.
1.350600 seconds.
1.373738 seconds

Please find attached the patch (including tests) that would add this improvement to Ruby trunk.

Best regards,

PS: I also changed the UNIVERSAL_TAG_NAME constant's name for OpenSSL::ASN1::EndOfContent from "EOC" to
"END_OF_CONTENT" because all other names are the uppercase versions of their corresponding classes, this
would have been the only exception to that rule.
Then I also exported two methods, default_tag and default_tag_of_class, for the ASN1 module. I needed
them for something I'm currently working on. These latter changes are independent of the performance
improvement described above.


class_tag_map.diff (7.09 KB) class_tag_map.diff MartinBosslet (Martin Bosslet), 01/24/2011 09:42 AM
class_tag_map2.diff (7.59 KB) class_tag_map2.diff MartinBosslet (Martin Bosslet), 01/24/2011 10:26 AM
class_tag_map3.diff (5.26 KB) class_tag_map3.diff MartinBosslet (Martin Bosslet), 01/25/2011 07:37 AM

Also available in: Atom PDF