Author image Daniel Dragan
and 1 contributors


Example::XS::FasterHashes - A tutorial with working examples for faster hashes in XS


    use Example::XS::FasterHashes;
    use Time::HiRes qw( time );
    $o = new Example::XS::FasterHashes;
    $time = time;
         for (int(rand 6)+1) {$o->get($_);}
    print "time was ".(time-$time)."\n";
    $time = time;
         for (int(rand 6)+1) {$o->getKC($_);}
    print "time was ".(time-$time)."\n";


This is a tutorial and a working example of precalculating key hash numbers and interacting with Perl's shared string table from XS. It is not a library your XS module can directly use. The intention is for you to copy paste the code or concepts in this module into your XS module. The code in this XS lib takes advantage of 2 parts of Perl's hash system. Perl compares the key's char * to the char * in the HEK, if they match, it will not perform an additional memcmp, see This module takes advantage of that, by passing to hv_fetch/etc the same char * that will be found in the HEK struct. The 2nd optimization is precalculating the hash number, which skips the hash calculating macro here,

There is a limitation though, ithreads. If a fork/clone/new thread happens, the char * in the HEK in the new thread will be different from the char * stored as a static in the DLL in the hv key cache, so the memcmp can not be skipped. The shared string table is per interp, not per process. The hash number being precalculated optimization is still done. A solution to the ithreads problem is Perl's TLS system, see "Safely-Storing-Static-Data-in-XS" in perlxs but that isn't implemented in this example. I don't know the performance impact of using Perl TLS since it adds 1 additional indirection to obtaining the key's char * and hash number and probably negativly affects the processor's prefetch ability. With the current non-ithreads design, in x86 the location of the char * is a machine code read only litteral offset to the current instruction pointer since the key's char * is stored in read/write static space in the DLL.

Read the source code for more the rest of the story. I suggest you delete this module from your hard disk after you installed it and benchmarked it, or don't even install it in the first place. It is not an API that you can directly use.



    $obj = new Example::XS::FasterHashes;

Creates a new Example::XS::FasterHashes object.



The traditional way of going through hashes of hashes in XS. Returns nothing. Takes 1 parameter, which is a random number from 1 through 7. This parameter prevents attempts at CPU caching.



The fast way of going through hashes of hashes in XS. Returns nothing. Takes 1 parameter, which is a random number from 1 through 7. This parameter prevents attempts at CPU caching. Benchmark this against "get", it will be faster. For me, using Example-XS-FasterHashes.t, the block of code which is using getKC is 15% faster than using "get"(). I never have measured the actual hv_fetches alone. The rand() might be 50% of the runtime, I really don't know. KC stands for Key Cache.


Bug fixes or performance ideas for this module should be submitted to the CPAN RT queue. Read the comments in the source code. Understand throughly whats being done before you integrate the code into your XS module. Use a DEBUGGING perl build and a C debugger with symbols. If you supply the wrong hash number, I don't know what will happen.


Daniel Dragan aka bulk88 email = bulkdd _at_


Copyright (C) 2012 by Daniel Dragan

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, at your option, any later version of Perl 5 you may have available.