2009-07-12 10 views
5

J'ai une fonction qui compare 2 chaînes char par char. J'avais besoin que ça tourne beaucoup plus vite que dans Ruby, donc j'ai utilisé RubyInline pour réécrire la fonction en C. Elle a augmenté la vitesse d'environ 100 fois. La fonction ressemble à ceci:Comment convertir un tableau ruby ​​en tableau C avec RubyInline?

require 'inline' 

    inline do |builder| 
    builder.c " 
     static int distance(char *s, char *t){ 
     ... 
     }" 
    end 

Cependant, j'ai besoin de comparer les chaînes Unicode. J'ai donc décidé d'utiliser unpack ("U *") et de comparer des tableaux d'entiers à la place. Je ne peux pas comprendre à partir d'une documentation rare à RubyInline comment passer les tableaux ruby ​​dans la fonction et comment les convertir en tableaux C. Toute aide est appréciée!

+0

Pas de problème, Tiens-moi au courant de ce que ça devient. J'adorerais voir votre mise en œuvre une fois terminé. –

+0

Voici le code de la distance de damerau_levenshtein: http://gist.github.com/147023 Ruby 1.8.7 fonctionne comme un charme, mais selfs sur Ruby 1.9.1 – dimus

+0

je mis à jour http: // essentiel. github.com/147023 de travailler avec 1.9.1 ruby ​​ainsi en utilisant l'aide de thnetos – dimus

Répondre

9

Cela a un bon aperçu de la façon d'accéder à Ruby objets de C: http://rubycentral.com/pickaxe/ext_ruby.html

inline do |builder| 
    builder.c " 
    static VALUE some_method(VALUE s) { 
     int s_len = RARRAY(s)->len; 
     int result = 0; 

     VALUE *s_arr = RARRAY(s)->ptr; 

     for(i = 0; i < s_len; i++) { 
     result += NUM2INT(s_arr[i]); // example of reference 
     } 

     return INT2NUM(result); // convert C int back into ruby Numeric 
    }" 
end 

Puis, en rubis, vous pouvez simplement transmettre des valeurs à lui comme:

object.some_method([1,2,3,4]) 

l'espoir que cela vous aide .

+0

Merci Corban, il ressemble exactement à ce dont j'ai besoin! – dimus

4

Vu le code de la réponse ci-dessus, voici le code qui fonctionnera pour Ruby 1.8.6 et 1.9.1:

inline do |builder| 
    builder.c " 
    static VALUE some_method(VALUE s) { 
     int s_len = RARRAY_LEN(s); 
     int result = 0; 
     int i = 0; 

     VALUE *s_arr = RARRAY_PTR(s); 

     for(i = 0; i < s_len; i++) { 
     result += NUM2INT(s_arr[i]); // example of reference 
     } 

     return INT2NUM(result); // convert C int back into ruby Numeric 
    }" 
end 

Hope this helps aussi :)

+0

Merci thnetos, il a résolu le problème, j'ai mis à jour l'exemple github gist – dimus

Questions connexes