2009-07-12 8 views
5

Ich habe eine Funktion, die 2 Zeichenketten durch Zeichen vergleicht. Ich brauchte es viel schneller als in Ruby, also habe ich RubyInline verwendet, um die Funktion in C neu zu schreiben. Es hat die Geschwindigkeit um das 100-fache erhöht. Die Funktion sieht so aus:Wie konvertiert man Ruby-Array mit RubyInline in C-Array?

require 'inline' 

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

aber ich muss Unicode-Strings vergleichen. Also entschloss ich mich, unpack ("U *") zu verwenden und Arrays von ganzen Zahlen zu vergleichen. Ich kann aus einer spärlichen Dokumentation zu RubyInline nicht herausfinden, wie man die Ruby-Arrays in die Funktion übergibt und wie man sie in C-Arrays umwandelt. Jede Hilfe wird geschätzt!

+0

Kein Problem, lass mich wissen wie es sich entwickelt. Würde gerne Ihre Implementierung sehen, wenn Sie fertig sind. –

+0

Hier ist der Code von damerau_levenshtein Entfernung: http://gist.github.com/147023 für Ruby 1.8.7 funktioniert wie ein Charme, aber Drosseln auf Rubin 1.9.1 – dimus

+0

I aktualisiert http: // Kern. github.com/147023 auch mit 1.9.1 Ruby zu arbeiten mit Hilfe von thnetos – dimus

Antwort

9

Dies hat einen guten Überblick über, wie man Zugang Rubin von C-Objekten: 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 

Dann in Ruby können Sie nur Werte, um es passieren mag:

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

Hoffnung, dies hilft Ihnen aus .

+0

Dank Corban, es sieht genau das aus, was ich brauche! – dimus

4

der Code aus der obigen Antwort, hier ist der Code, der für Ruby 1.8.6 und 1.9.1 funktionieren:

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 auch hilft :)

+0

Danke thnetos, es hat das Problem behoben, ich habe das Github-Beispiel aktualisiert – dimus

Verwandte Themen