2009-07-12 14 views
5

Mam funkcję, która porównuje 2 ciągi char char. Potrzebowałem go, aby działał znacznie szybciej niż w Ruby, więc użyłem RubyInline do przepisania funkcji w C. Zwiększyło to prędkość około 100 razy. Funkcja wygląda następująco:Jak przekonwertować tablicę ruby ​​na tablicę C za pomocą RubyInline?

require 'inline' 

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

Jednak muszę porównać ciągi Unicode. Zdecydowałem się więc na rozpakowanie ("U *") i zamiast tego porównałem tablice liczb całkowitych. Nie mogę się dowiedzieć od skąpej dokumentacji do RubyInline, jak przekazać tablice ruby ​​do funkcji i jak przekonwertować je na tablice C. Każda pomoc jest doceniana!

+0

nie ma problemu, daj mi znać, jak się okazuje. Chciałbym zobaczyć twoją implementację po zakończeniu. –

+0

Oto kod z odległości damerau_levenshtein: http://gist.github.com/147023 dla Ruby 1.8.7 działa jak czar, ale dławiki na ruby ​​1.9.1 – dimus

+0

zaktualizowałem http: // GIST. github.com/147023 do pracy z 1.9.1 ruby ​​i pomocą od Thnetos – dimus

Odpowiedz

9

To ma dobrą wybiegiem, jak uzyskać dostęp Ruby obiektów z 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 

Następnie w ruby ​​można po prostu przekazać wartości do niej podoba:

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

Nadzieja to pomaga się .

+0

Dzięki Corban, wygląda dokładnie to, czego potrzebuję! – dimus

4

Biorąc pod uwagę kod z powyższego odpowiedź, tutaj jest kod, który będzie pracować dla Ruby 1.8.6 i 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 

Nadzieja to pomaga również :)

+0

Dzięki Thnetos, naprawiłam problem, zaktualizowałam przykład Githuba – dimus

Powiązane problemy