Most efficient way to calculate hamming distance in ruby?

前端 未结 4 1652
予麋鹿
予麋鹿 2020-12-30 06:06

In ruby, what is the most efficient way to calculate the bit difference between two unsigned integers (e.g. the hamming distance)?

Eg, I have integer a = 2323409845

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-30 06:31

    Per the suggestion of mu is too short, I wrote a simple C extension to use __builtin_popcount , and using benchmark verified that it is at least 3X faster than ruby's optimized string functions..

    I looked at the following two tutorials:

    • Extending Ruby With C
    • Ruby Extension in C in 5 min

    In my program:

    require './FastPopcount/fastpopcount.so'
    include FastPopcount
    
    def hamming(a,b)
      popcount(a^b)
    end
    

    Then in the dir containing my program, I create a folder "PopCount" with the following files.

    extconf.rb:

    # Loads mkmf which is used to make makefiles for Ruby extensions
    require 'mkmf'
    
    # Give it a name
    extension_name = 'fastpopcount'
    
    # The destination
    dir_config(extension_name)
    
    # Do the work
    create_makefile(extension_name)
    

    popcount.c:

    // Include the Ruby headers and goodies
    #include "ruby.h"
    
    // Defining a space for information and references about the module to be stored internally
    VALUE FastPopcount = Qnil;
    
    // Prototype for the initialization method - Ruby calls this, not you
    void Init_fastpopcount();
    
    // Prototype for our method 'popcount' - methods are prefixed by 'method_' here
    VALUE method_popcount(int argc, VALUE *argv, VALUE self);
    
    // The initialization method for this module
    void Init_fastpopcount() {
        FastPopcount = rb_define_module("FastPopcount");
        rb_define_method(FastPopcount, "popcount", method_popcount, 1); 
    }
    
    // Our 'popcount' method.. it uses the builtin popcount
    VALUE method_popcount(int argc, VALUE *argv, VALUE self) {
        return INT2NUM(__builtin_popcount(NUM2UINT(argv)));
    }
    

    Then in the popcount directory run:

    ruby extconf.rb make

    Then run the program, and there you have it....fastest way to do hamming distance in ruby.

提交回复
热议问题