2009-07-12 35 views
5

Tôi có một hàm so sánh 2 chuỗi char bằng char. Tôi cần nó chạy nhanh hơn nhiều so với Ruby vì vậy tôi đã sử dụng RubyInline để viết lại hàm trong C. Nó đã tăng tốc độ gấp 100 lần. Hàm trông giống như sau:Làm thế nào để chuyển đổi mảng ruby ​​thành mảng C với RubyInline?

require 'inline' 

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

tuy nhiên tôi cần so sánh chuỗi unicode. Vì vậy, tôi quyết định sử dụng giải nén ("U *") và so sánh các mảng số nguyên thay thế. Tôi không thể tìm ra từ một tài liệu nhỏ gọn cho RubyInline cách truyền các mảng ruby ​​vào hàm và cách chuyển chúng thành các mảng C. Bất kỳ trợ giúp được đánh giá cao!

+0

giúp Không có vấn đề, Hãy cho tôi biết làm thế nào nó quay ra. Rất thích xem triển khai của bạn khi hoàn thành. –

+0

Đây là mã số của damerau_levenshtein khoảng cách: http://gist.github.com/147023 Đối với ruby ​​1.8.7 hoạt động như một nét duyên dáng, nhưng cuộn cảm trên ruby ​​1.9.1 – dimus

+0

Tôi cập nhật http: // gist. github.com/147023 để làm việc với 1.9.1 ruby ​​cũng như sử dụng trợ giúp từ thnetos – dimus

Trả lời

9

này có tóm tắt tốt về làm thế nào để truy cập của Ruby đối tượng từ 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 

Sau đó, trong ruby ​​bạn chỉ có thể vượt qua giá trị cho nó thích:

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

Hy vọng điều này sẽ giúp bạn ra .

+0

Cảm ơn Corban, có vẻ chính xác những gì tôi cần! – dimus

4

Với mã từ câu trả lời ở trên, đây là mã mà sẽ làm việc cho Ruby 1.8.6 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 

Hy vọng điều này cũng :)

+0

Cảm ơn thnetos, nó đã khắc phục được sự cố, tôi đã cập nhật ví dụ về github gist – dimus

Các vấn đề liên quan